diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b1ed9d116a..bb192279f6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -26,3 +26,6 @@ CHANGELOG.md @googleapis/cloud-aiplatform-model-builder-sdk @googleapis/cdpe-cloudai README.rst @googleapis/cloud-aiplatform-model-builder-sdk @googleapis/cdpe-cloudai setup.py @googleapis/cloud-aiplatform-model-builder-sdk @googleapis/cdpe-cloudai + +# Vertex AI product team-specific ownership +/google/cloud/aiplatform/constants/prediction.py @googleapis/vertex-prediction-team diff --git a/.kokoro/presubmit/presubmit.cfg b/.kokoro/presubmit/presubmit.cfg index 2dc85b80e7..66f7c8a934 100644 --- a/.kokoro/presubmit/presubmit.cfg +++ b/.kokoro/presubmit/presubmit.cfg @@ -3,7 +3,7 @@ # Run all sessions except system tests and docs builds env_vars: { key: "NOX_SESSION" - value: "unit-3.9 lint lint_setup_py blacken cover" + value: "unit lint lint_setup_py blacken cover" } # Run unit tests in parallel, splitting up by file diff --git a/.repo-metadata.json b/.repo-metadata.json index 46b1493222..58771655b6 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -2,7 +2,7 @@ "name": "aiplatform", "name_pretty": "AI Platform", "product_documentation": "https://cloud.google.com/ai-platform", - "client_documentation": "https://googleapis.dev/python/aiplatform/latest", + "client_documentation": "https://cloud.google.com/python/docs/reference/aiplatform/latest", "issue_tracker": "https://issuetracker.google.com/savedsearches/559744", "release_level": "ga", "language": "python", @@ -10,4 +10,4 @@ "repo": "googleapis/python-aiplatform", "distribution_name": "google-cloud-aiplatform", "api_id": "aiplatform.googleapis.com" -} \ No newline at end of file +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 533bf74efb..de2f469c48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,34 @@ # Changelog +## [1.8.0](https://www.github.com/googleapis/python-aiplatform/compare/v1.7.1...v1.8.0) (2021-12-03) + + +### Features + +* Add cloud profiler to training_utils ([6d5c7c4](https://www.github.com/googleapis/python-aiplatform/commit/6d5c7c42d1c352f161e4738c6dbbf540a032017b)) +* add enable_private_service_connect field to Endpoint feat: add id field to DeployedModel feat: add service_attachment field to PrivateEndpoints feat: add endpoint_id to CreateEndpointRequest and method signature to CreateEndpoint feat: add method... ([#878](https://www.github.com/googleapis/python-aiplatform/issues/878)) ([ca813be](https://www.github.com/googleapis/python-aiplatform/commit/ca813be08ec2620380b5a12b0d6cdc079e27ba79)) +* add enable_private_service_connect field to Endpoint feat: add id field to DeployedModel feat: add service_attachment field to PrivateEndpoints feat: add endpoint_id to CreateEndpointRequest and method signature to CreateEndpoint feat: add method... ([#879](https://www.github.com/googleapis/python-aiplatform/issues/879)) ([47e93b2](https://www.github.com/googleapis/python-aiplatform/commit/47e93b20843f30805b73cd6db214c8743f8bfc97)) +* add featurestore module including Featurestore, EntityType, and Feature classes; add get, update, delete, list methods in all featurestore classes; add search method in Feature class ([#850](https://www.github.com/googleapis/python-aiplatform/issues/850)) ([66745a6](https://www.github.com/googleapis/python-aiplatform/commit/66745a6ce13fb8b32dd7fbf3eb86e71bd291869b)) +* Add prediction container URI builder method ([#805](https://www.github.com/googleapis/python-aiplatform/issues/805)) ([91dd3c0](https://www.github.com/googleapis/python-aiplatform/commit/91dd3c0d5de72fac5b1dc8a9bc23d6cb431061a4)) +* default to custom job display name if experiment name looks like a custom job ID ([#833](https://www.github.com/googleapis/python-aiplatform/issues/833)) ([8b9376e](https://www.github.com/googleapis/python-aiplatform/commit/8b9376e9c961a751799f5b80d1b19917c8c353f8)) +* Support uploading local models ([#779](https://www.github.com/googleapis/python-aiplatform/issues/779)) ([bffbd9d](https://www.github.com/googleapis/python-aiplatform/commit/bffbd9d359edb099e661736a0c77269bb3a0c746)) +* Tensorboard v1 protos release ([#847](https://www.github.com/googleapis/python-aiplatform/issues/847)) ([e0fc3d9](https://www.github.com/googleapis/python-aiplatform/commit/e0fc3d9e4e8a7911f21671ea49818c5f84798d12)) +* updating Tensorboard related code to use v1 ([#851](https://www.github.com/googleapis/python-aiplatform/issues/851)) ([b613b26](https://www.github.com/googleapis/python-aiplatform/commit/b613b264524aaab2cb65e63a5487770736faa7c8)) +* Upgrade Tensorboard from v1beta1 to v1 ([#849](https://www.github.com/googleapis/python-aiplatform/issues/849)) ([c40ec85](https://www.github.com/googleapis/python-aiplatform/commit/c40ec85e1fca2bee6813f52712d063f96264ec2c)) + + +### Bug Fixes + +* Import error for cloud_profiler ([#869](https://www.github.com/googleapis/python-aiplatform/issues/869)) ([0f124e9](https://www.github.com/googleapis/python-aiplatform/commit/0f124e93a1ddead16c0018970f34e45c73d5ed81)) +* Support multiple instances in custom predict sample ([#857](https://www.github.com/googleapis/python-aiplatform/issues/857)) ([8cb4839](https://www.github.com/googleapis/python-aiplatform/commit/8cb483918bdbaeae34935eef2b3cd997c1ae89a3)) + + +### Documentation + +* Added comment for evaluation_id to python examples ([#860](https://www.github.com/googleapis/python-aiplatform/issues/860)) ([004bf5f](https://www.github.com/googleapis/python-aiplatform/commit/004bf5fa4cb2d66e36de7ec52dee8e2c8dd438ee)) +* Reverted IDs in model_service snippets test ([#871](https://www.github.com/googleapis/python-aiplatform/issues/871)) ([da747b5](https://www.github.com/googleapis/python-aiplatform/commit/da747b5ffca3c12b8d64bc80bfe93da5afde0d43)) +* Update name of BQ source parameter in samples ([#859](https://www.github.com/googleapis/python-aiplatform/issues/859)) ([f11b598](https://www.github.com/googleapis/python-aiplatform/commit/f11b598f9069f77e86631ada53941876aea010bc)) + ### [1.7.1](https://www.github.com/googleapis/python-aiplatform/compare/v1.7.0...v1.7.1) (2021-11-16) diff --git a/README.rst b/README.rst index 8673fe0a81..a59857a13b 100644 --- a/README.rst +++ b/README.rst @@ -22,7 +22,7 @@ Vertex SDK for Python .. |sample-tests| image:: https://storage.googleapis.com/cloud-devrel-public/python-aiplatform/badges/sdk-sample-tests.svg :target: https://storage.googleapis.com/cloud-devrel-public/python-aiplatform/badges/sdk-sample-tests.html .. _Vertex AI: https://cloud.google.com/vertex-ai/docs -.. _Client Library Documentation: https://googleapis.dev/python/aiplatform/latest +.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/aiplatform/latest .. _Product Documentation: https://cloud.google.com/vertex-ai/docs Quick Start @@ -464,6 +464,24 @@ To use Explanation Metadata in endpoint deployment and model upload: aiplatform.Model.upload(..., explanation_metadata=explanation_metadata) +Cloud Profiler +---------------------------- + +Cloud Profiler allows you to profile your remote Vertex AI Training jobs on demand and visualize the results in Vertex Tensorboard. + +To start using the profiler with TensorFlow, update your training script to include the following: + +.. code-block:: Python + + from google.cloud.aiplatform.training_utils import cloud_profiler + ... + cloud_profiler.init() + +Next, run the job with with a Vertex TensorBoard instance. For full details on how to do this, visit https://cloud.google.com/vertex-ai/docs/experiments/tensorboard-overview + +Finally, visit your TensorBoard in your Google Cloud Console, navigate to the "Profile" tab, and click the `Capture Profile` button. This will allow users to capture profiling statistics for the running jobs. + + Next Steps ~~~~~~~~~~ diff --git a/docs/aiplatform_v1/services.rst b/docs/aiplatform_v1/services.rst index aa15eabb25..0a6443a972 100644 --- a/docs/aiplatform_v1/services.rst +++ b/docs/aiplatform_v1/services.rst @@ -16,4 +16,5 @@ Services for Google Cloud Aiplatform v1 API pipeline_service prediction_service specialist_pool_service + tensorboard_service vizier_service diff --git a/docs/aiplatform_v1/tensorboard_service.rst b/docs/aiplatform_v1/tensorboard_service.rst new file mode 100644 index 0000000000..0fa17e10b8 --- /dev/null +++ b/docs/aiplatform_v1/tensorboard_service.rst @@ -0,0 +1,10 @@ +TensorboardService +------------------------------------ + +.. automodule:: google.cloud.aiplatform_v1.services.tensorboard_service + :members: + :inherited-members: + +.. automodule:: google.cloud.aiplatform_v1.services.tensorboard_service.pagers + :members: + :inherited-members: diff --git a/google/cloud/aiplatform/__init__.py b/google/cloud/aiplatform/__init__.py index a07296378e..3e206a5538 100644 --- a/google/cloud/aiplatform/__init__.py +++ b/google/cloud/aiplatform/__init__.py @@ -33,6 +33,11 @@ from google.cloud.aiplatform import explain from google.cloud.aiplatform import gapic from google.cloud.aiplatform import hyperparameter_tuning +from google.cloud.aiplatform.featurestore import ( + EntityType, + Feature, + Featurestore, +) from google.cloud.aiplatform.metadata import metadata from google.cloud.aiplatform.models import Endpoint from google.cloud.aiplatform.models import Model @@ -53,6 +58,7 @@ AutoMLTextTrainingJob, AutoMLVideoTrainingJob, ) +from google.cloud.aiplatform import helpers """ Usage: @@ -73,6 +79,7 @@ "explain", "gapic", "init", + "helpers", "hyperparameter_tuning", "log_params", "log_metrics", @@ -90,6 +97,9 @@ "CustomContainerTrainingJob", "CustomPythonPackageTrainingJob", "Endpoint", + "EntityType", + "Feature", + "Featurestore", "ImageDataset", "HyperparameterTuningJob", "Model", diff --git a/google/cloud/aiplatform/base.py b/google/cloud/aiplatform/base.py index c4eb2e4853..2ee4bf4635 100644 --- a/google/cloud/aiplatform/base.py +++ b/google/cloud/aiplatform/base.py @@ -898,6 +898,7 @@ def _list( project: Optional[str] = None, location: Optional[str] = None, credentials: Optional[auth_credentials.Credentials] = None, + parent: Optional[str] = None, ) -> List[VertexAiResourceNoun]: """Private method to list all instances of this Vertex AI Resource, takes a `cls_filter` arg to filter to a particular SDK resource @@ -925,6 +926,8 @@ def _list( credentials (auth_credentials.Credentials): Optional. Custom credentials to use to retrieve list. Overrides credentials set in aiplatform.init. + parent (str): + Optional. The parent resource name if any to retrieve resource list from. Returns: List[VertexAiResourceNoun] - A list of SDK resource objects @@ -934,12 +937,13 @@ def _list( ) # Fetch credentials once and re-use for all `_empty_constructor()` calls - creds = initializer.global_config.credentials + creds = resource.credentials resource_list_method = getattr(resource.api_client, resource._list_method) list_request = { - "parent": initializer.global_config.common_location_path( + "parent": parent + or initializer.global_config.common_location_path( project=project, location=location ), "filter": filter, @@ -1029,6 +1033,7 @@ def list( project: Optional[str] = None, location: Optional[str] = None, credentials: Optional[auth_credentials.Credentials] = None, + parent: Optional[str] = None, ) -> List[VertexAiResourceNoun]: """List all instances of this Vertex AI Resource. @@ -1057,6 +1062,8 @@ def list( credentials (auth_credentials.Credentials): Optional. Custom credentials to use to retrieve list. Overrides credentials set in aiplatform.init. + parent (str): + Optional. The parent resource name if any to retrieve list from. Returns: List[VertexAiResourceNoun] - A list of SDK resource objects @@ -1068,6 +1075,7 @@ def list( project=project, location=location, credentials=credentials, + parent=parent, ) @optional_sync() diff --git a/google/cloud/aiplatform/compat/__init__.py b/google/cloud/aiplatform/compat/__init__.py index fd814bbc37..d435cf9578 100644 --- a/google/cloud/aiplatform/compat/__init__.py +++ b/google/cloud/aiplatform/compat/__init__.py @@ -27,6 +27,10 @@ services.dataset_service_client = services.dataset_service_client_v1beta1 services.endpoint_service_client = services.endpoint_service_client_v1beta1 + services.featurestore_online_serving_service_client = ( + services.featurestore_online_serving_service_client_v1beta1 + ) + services.featurestore_service_client = services.featurestore_service_client_v1beta1 services.job_service_client = services.job_service_client_v1beta1 services.model_service_client = services.model_service_client_v1beta1 services.pipeline_service_client = services.pipeline_service_client_v1beta1 @@ -53,11 +57,19 @@ types.encryption_spec = types.encryption_spec_v1beta1 types.endpoint = types.endpoint_v1beta1 types.endpoint_service = types.endpoint_service_v1beta1 + types.entity_type = types.entity_type_v1beta1 types.env_var = types.env_var_v1beta1 types.event = types.event_v1beta1 types.execution = types.execution_v1beta1 types.explanation = types.explanation_v1beta1 types.explanation_metadata = types.explanation_metadata_v1beta1 + types.feature = types.feature_v1beta1 + types.feature_monitoring_stats = types.feature_monitoring_stats_v1beta1 + types.feature_selector = types.feature_selector_v1beta1 + types.featurestore = types.featurestore_v1beta1 + types.featurestore_monitoring = types.featurestore_monitoring_v1beta1 + types.featurestore_online_service = types.featurestore_online_service_v1beta1 + types.featurestore_service = types.featurestore_service_v1beta1 types.hyperparameter_tuning_job = types.hyperparameter_tuning_job_v1beta1 types.io = types.io_v1beta1 types.job_service = types.job_service_v1beta1 @@ -77,23 +89,29 @@ types.specialist_pool = types.specialist_pool_v1beta1 types.specialist_pool_service = types.specialist_pool_service_v1beta1 types.study = types.study_v1beta1 - types.training_pipeline = types.training_pipeline_v1beta1 + types.tensorboard = types.tensorboard_v1beta1 types.tensorboard_service = types.tensorboard_service_v1beta1 types.tensorboard_data = types.tensorboard_data_v1beta1 types.tensorboard_experiment = types.tensorboard_experiment_v1beta1 types.tensorboard_run = types.tensorboard_run_v1beta1 types.tensorboard_service = types.tensorboard_service_v1beta1 types.tensorboard_time_series = types.tensorboard_time_series_v1beta1 + types.training_pipeline = types.training_pipeline_v1beta1 if DEFAULT_VERSION == V1: services.dataset_service_client = services.dataset_service_client_v1 services.endpoint_service_client = services.endpoint_service_client_v1 + services.featurestore_online_serving_service_client = ( + services.featurestore_online_serving_service_client_v1 + ) + services.featurestore_service_client = services.featurestore_service_client_v1 services.job_service_client = services.job_service_client_v1 services.model_service_client = services.model_service_client_v1 services.pipeline_service_client = services.pipeline_service_client_v1 services.prediction_service_client = services.prediction_service_client_v1 services.specialist_pool_service_client = services.specialist_pool_service_client_v1 + services.tensorboard_service_client = services.tensorboard_service_client_v1 types.accelerator_type = types.accelerator_type_v1 types.annotation = types.annotation_v1 @@ -111,11 +129,18 @@ types.encryption_spec = types.encryption_spec_v1 types.endpoint = types.endpoint_v1 types.endpoint_service = types.endpoint_service_v1 + types.entity_type = types.entity_type_v1 types.env_var = types.env_var_v1 types.event = types.event_v1 types.execution = types.execution_v1 types.explanation = types.explanation_v1 types.explanation_metadata = types.explanation_metadata_v1 + types.feature = types.feature_v1 + types.feature_monitoring_stats = types.feature_monitoring_stats_v1 + types.feature_selector = types.feature_selector_v1 + types.featurestore = types.featurestore_v1 + types.featurestore_online_service = types.featurestore_online_service_v1 + types.featurestore_service = types.featurestore_service_v1 types.hyperparameter_tuning_job = types.hyperparameter_tuning_job_v1 types.io = types.io_v1 types.job_service = types.job_service_v1 @@ -135,6 +160,13 @@ types.specialist_pool = types.specialist_pool_v1 types.specialist_pool_service = types.specialist_pool_service_v1 types.study = types.study_v1 + types.tensorboard = types.tensorboard_v1 + types.tensorboard_service = types.tensorboard_service_v1 + types.tensorboard_data = types.tensorboard_data_v1 + types.tensorboard_experiment = types.tensorboard_experiment_v1 + types.tensorboard_run = types.tensorboard_run_v1 + types.tensorboard_service = types.tensorboard_service_v1 + types.tensorboard_time_series = types.tensorboard_time_series_v1 types.training_pipeline = types.training_pipeline_v1 __all__ = ( diff --git a/google/cloud/aiplatform/compat/services/__init__.py b/google/cloud/aiplatform/compat/services/__init__.py index 098d3ff861..f8545a688c 100644 --- a/google/cloud/aiplatform/compat/services/__init__.py +++ b/google/cloud/aiplatform/compat/services/__init__.py @@ -21,6 +21,12 @@ from google.cloud.aiplatform_v1beta1.services.endpoint_service import ( client as endpoint_service_client_v1beta1, ) +from google.cloud.aiplatform_v1beta1.services.featurestore_online_serving_service import ( + client as featurestore_online_serving_service_client_v1beta1, +) +from google.cloud.aiplatform_v1beta1.services.featurestore_service import ( + client as featurestore_service_client_v1beta1, +) from google.cloud.aiplatform_v1beta1.services.job_service import ( client as job_service_client_v1beta1, ) @@ -49,6 +55,12 @@ from google.cloud.aiplatform_v1.services.endpoint_service import ( client as endpoint_service_client_v1, ) +from google.cloud.aiplatform_v1.services.featurestore_online_serving_service import ( + client as featurestore_online_serving_service_client_v1, +) +from google.cloud.aiplatform_v1.services.featurestore_service import ( + client as featurestore_service_client_v1, +) from google.cloud.aiplatform_v1.services.job_service import ( client as job_service_client_v1, ) @@ -67,20 +79,28 @@ from google.cloud.aiplatform_v1.services.specialist_pool_service import ( client as specialist_pool_service_client_v1, ) +from google.cloud.aiplatform_v1.services.tensorboard_service import ( + client as tensorboard_service_client_v1, +) __all__ = ( # v1 dataset_service_client_v1, endpoint_service_client_v1, + featurestore_online_serving_service_client_v1beta1, + featurestore_service_client_v1beta1, job_service_client_v1, metadata_service_client_v1, model_service_client_v1, pipeline_service_client_v1, prediction_service_client_v1, specialist_pool_service_client_v1, + tensorboard_service_client_v1, # v1beta1 dataset_service_client_v1beta1, endpoint_service_client_v1beta1, + featurestore_online_serving_service_client_v1, + featurestore_service_client_v1, job_service_client_v1beta1, model_service_client_v1beta1, pipeline_service_client_v1beta1, diff --git a/google/cloud/aiplatform/compat/types/__init__.py b/google/cloud/aiplatform/compat/types/__init__.py index 1ed76d1e25..a2a82fdca9 100644 --- a/google/cloud/aiplatform/compat/types/__init__.py +++ b/google/cloud/aiplatform/compat/types/__init__.py @@ -32,11 +32,19 @@ encryption_spec as encryption_spec_v1beta1, endpoint as endpoint_v1beta1, endpoint_service as endpoint_service_v1beta1, + entity_type as entity_type_v1beta1, env_var as env_var_v1beta1, event as event_v1beta1, execution as execution_v1beta1, explanation as explanation_v1beta1, explanation_metadata as explanation_metadata_v1beta1, + feature as feature_v1beta1, + feature_monitoring_stats as feature_monitoring_stats_v1beta1, + feature_selector as feature_selector_v1beta1, + featurestore as featurestore_v1beta1, + featurestore_monitoring as featurestore_monitoring_v1beta1, + featurestore_online_service as featurestore_online_service_v1beta1, + featurestore_service as featurestore_service_v1beta1, hyperparameter_tuning_job as hyperparameter_tuning_job_v1beta1, io as io_v1beta1, job_service as job_service_v1beta1, @@ -57,13 +65,13 @@ specialist_pool as specialist_pool_v1beta1, specialist_pool_service as specialist_pool_service_v1beta1, study as study_v1beta1, - training_pipeline as training_pipeline_v1beta1, tensorboard as tensorboard_v1beta1, tensorboard_data as tensorboard_data_v1beta1, tensorboard_experiment as tensorboard_experiment_v1beta1, tensorboard_run as tensorboard_run_v1beta1, tensorboard_service as tensorboard_service_v1beta1, tensorboard_time_series as tensorboard_time_series_v1beta1, + training_pipeline as training_pipeline_v1beta1, ) from google.cloud.aiplatform_v1.types import ( accelerator_type as accelerator_type_v1, @@ -82,11 +90,18 @@ encryption_spec as encryption_spec_v1, endpoint as endpoint_v1, endpoint_service as endpoint_service_v1, + entity_type as entity_type_v1, env_var as env_var_v1, event as event_v1, execution as execution_v1, explanation as explanation_v1, explanation_metadata as explanation_metadata_v1, + feature as feature_v1, + feature_monitoring_stats as feature_monitoring_stats_v1, + feature_selector as feature_selector_v1, + featurestore as featurestore_v1, + featurestore_online_service as featurestore_online_service_v1, + featurestore_service as featurestore_service_v1, hyperparameter_tuning_job as hyperparameter_tuning_job_v1, io as io_v1, job_service as job_service_v1, @@ -107,6 +122,12 @@ specialist_pool as specialist_pool_v1, specialist_pool_service as specialist_pool_service_v1, study as study_v1, + tensorboard as tensorboard_v1, + tensorboard_data as tensorboard_data_v1, + tensorboard_experiment as tensorboard_experiment_v1, + tensorboard_run as tensorboard_run_v1, + tensorboard_service as tensorboard_service_v1, + tensorboard_time_series as tensorboard_time_series_v1, training_pipeline as training_pipeline_v1, ) @@ -128,11 +149,18 @@ encryption_spec_v1, endpoint_v1, endpoint_service_v1, + entity_type_v1, env_var_v1, event_v1, execution_v1, explanation_v1, explanation_metadata_v1, + feature_v1, + feature_monitoring_stats_v1, + feature_selector_v1, + featurestore_v1, + featurestore_online_service_v1, + featurestore_service_v1, hyperparameter_tuning_job_v1, io_v1, job_service_v1, @@ -152,6 +180,12 @@ prediction_service_v1, specialist_pool_v1, specialist_pool_service_v1, + tensorboard_v1, + tensorboard_data_v1, + tensorboard_experiment_v1, + tensorboard_run_v1, + tensorboard_service_v1, + tensorboard_time_series_v1, training_pipeline_v1, # v1beta1 accelerator_type_v1beta1, @@ -170,11 +204,19 @@ encryption_spec_v1beta1, endpoint_v1beta1, endpoint_service_v1beta1, + entity_type_v1beta1, env_var_v1beta1, event_v1beta1, execution_v1beta1, explanation_v1beta1, explanation_metadata_v1beta1, + feature_v1beta1, + feature_monitoring_stats_v1beta1, + feature_selector_v1beta1, + featurestore_v1beta1, + featurestore_monitoring_v1beta1, + featurestore_online_service_v1beta1, + featurestore_service_v1beta1, hyperparameter_tuning_job_v1beta1, io_v1beta1, job_service_v1beta1, @@ -194,13 +236,11 @@ prediction_service_v1beta1, specialist_pool_v1beta1, specialist_pool_service_v1beta1, - training_pipeline_v1beta1, - metadata_service_v1beta1, tensorboard_v1beta1, - tensorboard_service_v1beta1, tensorboard_data_v1beta1, tensorboard_experiment_v1beta1, tensorboard_run_v1beta1, tensorboard_service_v1beta1, tensorboard_time_series_v1beta1, + training_pipeline_v1beta1, ) diff --git a/google/cloud/aiplatform/constants/__init__.py b/google/cloud/aiplatform/constants/__init__.py new file mode 100644 index 0000000000..95f437a335 --- /dev/null +++ b/google/cloud/aiplatform/constants/__init__.py @@ -0,0 +1,18 @@ +# 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 +# +# 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. + +from google.cloud.aiplatform.constants import base +from google.cloud.aiplatform.constants import prediction + +__all__ = ("base", "prediction") diff --git a/google/cloud/aiplatform/constants.py b/google/cloud/aiplatform/constants/base.py similarity index 100% rename from google/cloud/aiplatform/constants.py rename to google/cloud/aiplatform/constants/base.py diff --git a/google/cloud/aiplatform/constants/prediction.py b/google/cloud/aiplatform/constants/prediction.py new file mode 100644 index 0000000000..682978ea58 --- /dev/null +++ b/google/cloud/aiplatform/constants/prediction.py @@ -0,0 +1,138 @@ +# 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 +# +# 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. + +import re + +from collections import defaultdict + +# [region]-docker.pkg.dev/vertex-ai/prediction/[framework]-[accelerator].[version]:latest +CONTAINER_URI_PATTERN = re.compile( + r"(?P[\w]+)\-docker\.pkg\.dev\/vertex\-ai\/prediction\/" + r"(?P[\w]+)\-(?P[\w]+)\.(?P[\d-]+):latest" +) + +SKLEARN = "sklearn" +TF = "tf" +TF2 = "tf2" +XGBOOST = "xgboost" + +XGBOOST_CONTAINER_URIS = [ + "us-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-4:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-4:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-4:latest", + "us-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-3:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-3:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-3:latest", + "us-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-2:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-2:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-2:latest", + "us-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-1:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-1:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-1:latest", + "us-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.0-90:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.0-90:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.0-90:latest", + "us-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.0-82:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.0-82:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.0-82:latest", +] + +SKLEARN_CONTAINER_URIS = [ + "us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-0:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-0:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-0:latest", + "us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-24:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-24:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-24:latest", + "us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-23:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-23:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-23:latest", + "us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-22:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-22:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-22:latest", + "us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-20:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-20:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-20:latest", +] + +TF_CONTAINER_URIS = [ + "us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-7:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-7:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-7:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-7:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-7:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-7:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-6:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-6:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-6:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-6:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-6:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-6:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-5:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-5:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-5:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-5:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-5:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-5:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-4:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-4:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-4:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-4:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-4:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-4:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-3:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-3:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-3:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-3:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-3:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-3:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-2:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-2:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-2:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-2:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-2:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-2:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-1:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-1:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-1:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf-cpu.1-15:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf-cpu.1-15:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf-cpu.1-15:latest", + "us-docker.pkg.dev/vertex-ai/prediction/tf-gpu.1-15:latest", + "europe-docker.pkg.dev/vertex-ai/prediction/tf-gpu.1-15:latest", + "asia-docker.pkg.dev/vertex-ai/prediction/tf-gpu.1-15:latest", +] + +SERVING_CONTAINER_URIS = ( + SKLEARN_CONTAINER_URIS + TF_CONTAINER_URIS + XGBOOST_CONTAINER_URIS +) + +# Map of all first-party prediction containers +d = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(str)))) + +for container_uri in SERVING_CONTAINER_URIS: + m = CONTAINER_URI_PATTERN.match(container_uri) + region, framework, accelerator, version = m[1], m[2], m[3], m[4] + version = version.replace("-", ".") + + if framework in (TF2, TF): # Store both `tf`, `tf2` as `tensorflow` + framework = "tensorflow" + + d[region][framework][accelerator][version] = container_uri + +_SERVING_CONTAINER_URI_MAP = d + +_SERVING_CONTAINER_DOCUMENTATION_URL = ( + "https://cloud.google.com/vertex-ai/docs/predictions/pre-built-containers" +) diff --git a/google/cloud/aiplatform/featurestore/__init__.py b/google/cloud/aiplatform/featurestore/__init__.py new file mode 100644 index 0000000000..883f72dd26 --- /dev/null +++ b/google/cloud/aiplatform/featurestore/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +from google.cloud.aiplatform.featurestore.entity_type import EntityType +from google.cloud.aiplatform.featurestore.feature import Feature +from google.cloud.aiplatform.featurestore.featurestore import Featurestore + +__all__ = ( + "EntityType", + "Feature", + "Featurestore", +) diff --git a/google/cloud/aiplatform/featurestore/entity_type.py b/google/cloud/aiplatform/featurestore/entity_type.py new file mode 100644 index 0000000000..327bf1931d --- /dev/null +++ b/google/cloud/aiplatform/featurestore/entity_type.py @@ -0,0 +1,383 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +from typing import Dict, List, Optional, Sequence, Tuple + +from google.auth import credentials as auth_credentials +from google.protobuf import field_mask_pb2 + +from google.cloud.aiplatform import base +from google.cloud.aiplatform.compat.types import entity_type as gca_entity_type +from google.cloud.aiplatform import featurestore +from google.cloud.aiplatform import utils +from google.cloud.aiplatform.utils import featurestore_utils + +_LOGGER = base.Logger(__name__) +_ALL_FEATURE_IDS = "*" + + +class EntityType(base.VertexAiResourceNounWithFutureManager): + """Managed entityType resource for Vertex AI.""" + + client_class = utils.FeaturestoreClientWithOverride + + _is_client_prediction_client = False + _resource_noun = None + _getter_method = "get_entity_type" + _list_method = "list_entity_types" + _delete_method = "delete_entity_type" + + def __init__( + self, + entity_type_name: str, + featurestore_id: Optional[str] = None, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, + ): + """Retrieves an existing managed entityType given an entityType resource name or an entity_type ID. + + Example Usage: + + my_entity_type = aiplatform.EntityType( + entity_type_name='projects/123/locations/us-central1/featurestores/my_featurestore_id/\ + entityTypes/my_entity_type_id' + ) + or + my_entity_type = aiplatform.EntityType( + entity_type_name='my_entity_type_id', + featurestore_id='my_featurestore_id', + ) + + Args: + entity_type_name (str): + Required. A fully-qualified entityType resource name or an entity_type ID. + Example: "projects/123/locations/us-central1/featurestores/my_featurestore_id/entityTypes/my_entity_type_id" + or "my_entity_type_id" when project and location are initialized or passed, with featurestore_id passed. + featurestore_id (str): + Optional. Featurestore ID to retrieve entityType from, when entity_type_name is passed as entity_type ID. + project (str): + Optional. Project to retrieve entityType from. If not set, project + set in aiplatform.init will be used. + location (str): + Optional. Location to retrieve entityType from. If not set, location + set in aiplatform.init will be used. + credentials (auth_credentials.Credentials): + Optional. Custom credentials to use to retrieve this EntityType. Overrides + credentials set in aiplatform.init. + """ + + ( + featurestore_id, + _, + ) = featurestore_utils.validate_and_get_entity_type_resource_ids( + entity_type_name=entity_type_name, featurestore_id=featurestore_id + ) + + # TODO(b/208269923): Temporary workaround, update when base class supports nested resource + self._resource_noun = f"featurestores/{featurestore_id}/entityTypes" + + super().__init__( + project=project, + location=location, + credentials=credentials, + resource_name=entity_type_name, + ) + self._gca_resource = self._get_gca_resource(resource_name=entity_type_name) + + @property + def featurestore_name(self) -> str: + """Full qualified resource name of the managed featurestore in which this EntityType is.""" + entity_type_name_components = featurestore_utils.CompatFeaturestoreServiceClient.parse_entity_type_path( + path=self.resource_name + ) + return featurestore_utils.CompatFeaturestoreServiceClient.featurestore_path( + project=entity_type_name_components["project"], + location=entity_type_name_components["location"], + featurestore=entity_type_name_components["featurestore"], + ) + + def get_featurestore(self) -> "featurestore.Featurestore": + """Retrieves the managed featurestore in which this EntityType is. + + Returns: + featurestore.Featurestore - The managed featurestore in which this EntityType is. + """ + return featurestore.Featurestore(self.featurestore_name) + + def get_feature(self, feature_id: str) -> "featurestore.Feature": + """Retrieves an existing managed feature in this EntityType. + + Args: + feature_id (str): + Required. The managed feature resource ID in this EntityType. + Returns: + featurestore.Feature - The managed feature resource object. + """ + entity_type_name_components = featurestore_utils.CompatFeaturestoreServiceClient.parse_entity_type_path( + path=self.resource_name + ) + + return featurestore.Feature( + feature_name=featurestore_utils.CompatFeaturestoreServiceClient.feature_path( + project=entity_type_name_components["project"], + location=entity_type_name_components["location"], + featurestore=entity_type_name_components["featurestore"], + entity_type=entity_type_name_components["entity_type"], + feature=feature_id, + ) + ) + + def update( + self, + description: Optional[str] = None, + labels: Optional[Dict[str, str]] = None, + request_metadata: Optional[Sequence[Tuple[str, str]]] = (), + ) -> "EntityType": + """Updates an existing managed entityType resource. + + Example Usage: + + my_entity_type = aiplatform.EntityType( + entity_type_name='my_entity_type_id', + featurestore_id='my_featurestore_id', + ) + my_entity_type.update( + description='update my description', + ) + + Args: + description (str): + Optional. Description of the EntityType. + labels (Dict[str, str]): + Optional. The labels with user-defined + metadata to organize your EntityTypes. + Label keys and values can be no longer than 64 + characters (Unicode codepoints), can only + contain lowercase letters, numeric characters, + underscores and dashes. International characters + are allowed. + See https://goo.gl/xmQnxf for more information + on and examples of labels. No more than 64 user + labels can be associated with one Feature + (System labels are excluded)." + System reserved label keys are prefixed with + "aiplatform.googleapis.com/" and are immutable. + request_metadata (Sequence[Tuple[str, str]]): + Optional. Strings which should be sent along with the request as metadata. + Returns: + EntityType - The updated entityType resource object. + """ + update_mask = list() + + if description: + update_mask.append("description") + + if labels: + utils.validate_labels(labels) + update_mask.append("labels") + + update_mask = field_mask_pb2.FieldMask(paths=update_mask) + + gapic_entity_type = gca_entity_type.EntityType( + name=self.resource_name, description=description, labels=labels, + ) + + _LOGGER.log_action_start_against_resource( + "Updating", "entityType", self, + ) + + update_entity_type_lro = self.api_client.update_entity_type( + entity_type=gapic_entity_type, + update_mask=update_mask, + metadata=request_metadata, + ) + + _LOGGER.log_action_started_against_resource_with_lro( + "Update", "entityType", self.__class__, update_entity_type_lro + ) + + update_entity_type_lro.result() + + _LOGGER.log_action_completed_against_resource("entityType", "updated", self) + + return self + + @classmethod + def list( + cls, + featurestore_name: str, + filter: Optional[str] = None, + order_by: Optional[str] = None, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, + ) -> List["EntityType"]: + """Lists existing managed entityType resources in a featurestore, given a featurestore resource name or a featurestore ID. + + Example Usage: + + my_entityTypes = aiplatform.EntityType.list( + featurestore_name='projects/123/locations/us-central1/featurestores/my_featurestore_id' + ) + or + my_entityTypes = aiplatform.EntityType.list( + featurestore_name='my_featurestore_id' + ) + + Args: + featurestore_name (str): + Required. A fully-qualified featurestore resource name or a featurestore ID to list entityTypes in + Example: "projects/123/locations/us-central1/featurestores/my_featurestore_id" + or "my_featurestore_id" when project and location are initialized or passed. + filter (str): + Optional. Lists the EntityTypes that match the filter expression. The + following filters are supported: + + - ``create_time``: Supports ``=``, ``!=``, ``<``, ``>``, + ``>=``, and ``<=`` comparisons. Values must be in RFC + 3339 format. + - ``update_time``: Supports ``=``, ``!=``, ``<``, ``>``, + ``>=``, and ``<=`` comparisons. Values must be in RFC + 3339 format. + - ``labels``: Supports key-value equality as well as key + presence. + + Examples: + + - ``create_time > \"2020-01-31T15:30:00.000000Z\" OR update_time > \"2020-01-31T15:30:00.000000Z\"`` + --> EntityTypes created or updated after + 2020-01-31T15:30:00.000000Z. + - ``labels.active = yes AND labels.env = prod`` --> + EntityTypes having both (active: yes) and (env: prod) + labels. + - ``labels.env: *`` --> Any EntityType which has a label + with 'env' as the key. + 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. + + Supported fields: + + - ``entity_type_id`` + - ``create_time`` + - ``update_time`` + project (str): + Optional. Project to list entityTypes in. If not set, project + set in aiplatform.init will be used. + location (str): + Optional. Location to list entityTypes in. If not set, location + set in aiplatform.init will be used. + credentials (auth_credentials.Credentials): + Optional. Custom credentials to use to list entityTypes. Overrides + credentials set in aiplatform.init. + + Returns: + List[EntityType] - A list of managed entityType resource objects + """ + + return cls._list( + filter=filter, + order_by=order_by, + project=project, + location=location, + credentials=credentials, + parent=utils.full_resource_name( + resource_name=featurestore_name, + resource_noun="featurestores", + project=project, + location=location, + ), + ) + + def list_features( + self, filter: Optional[str] = None, order_by: Optional[str] = None, + ) -> List["featurestore.Feature"]: + """Lists existing managed feature resources in this EntityType. + + Example Usage: + + my_entity_type = aiplatform.EntityType( + entity_type_name='my_entity_type_id', + featurestore_id='my_featurestore_id', + ) + my_entityType.list_features() + + Args: + filter (str): + Optional. Lists the Features that match the filter expression. The + following filters are supported: + + - ``value_type``: Supports = and != comparisons. + - ``create_time``: Supports =, !=, <, >, >=, and <= + comparisons. Values must be in RFC 3339 format. + - ``update_time``: Supports =, !=, <, >, >=, and <= + comparisons. Values must be in RFC 3339 format. + - ``labels``: Supports key-value equality as well as key + presence. + + Examples: + + - ``value_type = DOUBLE`` --> Features whose type is + DOUBLE. + - ``create_time > \"2020-01-31T15:30:00.000000Z\" OR update_time > \"2020-01-31T15:30:00.000000Z\"`` + --> EntityTypes created or updated after + 2020-01-31T15:30:00.000000Z. + - ``labels.active = yes AND labels.env = prod`` --> + Features having both (active: yes) and (env: prod) + labels. + - ``labels.env: *`` --> Any Feature which has a label with + 'env' as the key. + 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. Supported fields: + + - ``feature_id`` + - ``value_type`` + - ``create_time`` + - ``update_time`` + + Returns: + List[featurestore.Feature] - A list of managed feature resource objects. + """ + return featurestore.Feature.list( + entity_type_name=self.resource_name, filter=filter, order_by=order_by, + ) + + @base.optional_sync() + def delete_features(self, feature_ids: List[str], sync: bool = True,) -> None: + """Deletes feature resources in this EntityType given their feature IDs. + WARNING: This deletion is permanent. + + Args: + feature_ids (List[str]): + Required. The list of feature IDs to be deleted. + sync (bool): + Optional. Whether to execute this deletion synchronously. If False, this method + will be executed in concurrent Future and any downstream object will + be immediately returned and synced when the Future has completed. + """ + features = [] + for feature_id in feature_ids: + feature = self.get_feature(feature_id=feature_id) + feature.delete(sync=False) + features.append(feature) + + for feature in features: + feature.wait() diff --git a/google/cloud/aiplatform/featurestore/feature.py b/google/cloud/aiplatform/featurestore/feature.py new file mode 100644 index 0000000000..ab199d0c57 --- /dev/null +++ b/google/cloud/aiplatform/featurestore/feature.py @@ -0,0 +1,463 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +from typing import Dict, List, Optional, Sequence, Tuple + +from google.auth import credentials as auth_credentials +from google.protobuf import field_mask_pb2 + +from google.cloud.aiplatform import base +from google.cloud.aiplatform.compat.types import feature as gca_feature +from google.cloud.aiplatform import featurestore +from google.cloud.aiplatform import initializer +from google.cloud.aiplatform import utils +from google.cloud.aiplatform.utils import featurestore_utils + +_LOGGER = base.Logger(__name__) + + +class Feature(base.VertexAiResourceNounWithFutureManager): + """Managed feature resource for Vertex AI.""" + + client_class = utils.FeaturestoreClientWithOverride + + _is_client_prediction_client = False + _resource_noun = None + _getter_method = "get_feature" + _list_method = "list_features" + _delete_method = "delete_feature" + + def __init__( + self, + feature_name: str, + featurestore_id: Optional[str] = None, + entity_type_id: Optional[str] = None, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, + ): + """Retrieves an existing managed feature given a feature resource name or a feature ID. + + Example Usage: + + my_feature = aiplatform.Feature( + feature_name='projects/123/locations/us-central1/featurestores/my_featurestore_id/\ + entityTypes/my_entity_type_id/features/my_feature_id' + ) + or + my_feature = aiplatform.Feature( + feature_name='my_feature_id', + featurestore_id='my_featurestore_id', + entity_type_id='my_entity_type_id', + ) + + Args: + feature_name (str): + Required. A fully-qualified feature resource name or a feature ID. + Example: "projects/123/locations/us-central1/featurestores/my_featurestore_id/entityTypes/my_entity_type_id/features/my_feature_id" + or "my_feature_id" when project and location are initialized or passed, with featurestore_id and entity_type_id passed. + featurestore_id (str): + Optional. Featurestore ID to retrieve feature from, when feature_name is passed as Feature ID. + entity_type_id (str): + Optional. EntityType ID to retrieve feature from, when feature_name is passed as Feature ID. + project (str): + Optional. Project to retrieve feature from. If not set, project + set in aiplatform.init will be used. + location (str): + Optional. Location to retrieve feature from. If not set, location + set in aiplatform.init will be used. + credentials (auth_credentials.Credentials): + Optional. Custom credentials to use to retrieve this Feature. Overrides + credentials set in aiplatform.init. + """ + ( + featurestore_id, + entity_type_id, + _, + ) = featurestore_utils.validate_and_get_feature_resource_ids( + feature_name=feature_name, + entity_type_id=entity_type_id, + featurestore_id=featurestore_id, + ) + + # TODO(b/208269923): Temporary workaround, update when base class supports nested resource + self._resource_noun = ( + f"featurestores/{featurestore_id}/entityTypes/{entity_type_id}/features" + ) + + super().__init__( + project=project, + location=location, + credentials=credentials, + resource_name=feature_name, + ) + self._gca_resource = self._get_gca_resource(resource_name=feature_name) + + @property + def featurestore_name(self) -> str: + """Full qualified resource name of the managed featurestore in which this Feature is.""" + feature_path_components = featurestore_utils.CompatFeaturestoreServiceClient.parse_feature_path( + path=self.resource_name + ) + + return featurestore_utils.CompatFeaturestoreServiceClient.featurestore_path( + project=feature_path_components["project"], + location=feature_path_components["location"], + featurestore=feature_path_components["featurestore"], + ) + + def get_featurestore(self) -> "featurestore.Featurestore": + """Retrieves the managed featurestore in which this Feature is. + + Returns: + featurestore.Featurestore - The managed featurestore in which this Feature is. + """ + return featurestore.Featurestore(featurestore_name=self.featurestore_name) + + @property + def entity_type_name(self) -> str: + """Full qualified resource name of the managed entityType in which this Feature is.""" + feature_path_components = featurestore_utils.CompatFeaturestoreServiceClient.parse_feature_path( + path=self.resource_name + ) + + return featurestore_utils.CompatFeaturestoreServiceClient.entity_type_path( + project=feature_path_components["project"], + location=feature_path_components["location"], + featurestore=feature_path_components["featurestore"], + entity_type=feature_path_components["entity_type"], + ) + + def get_entity_type(self) -> "featurestore.EntityType": + """Retrieves the managed entityType in which this Feature is. + + Returns: + featurestore.EntityType - The managed entityType in which this Feature is. + """ + return featurestore.EntityType(entity_type_name=self.entity_type_name) + + def update( + self, + description: Optional[str] = None, + labels: Optional[Dict[str, str]] = None, + request_metadata: Optional[Sequence[Tuple[str, str]]] = (), + ) -> "Feature": + """Updates an existing managed feature resource. + + Example Usage: + + my_feature = aiplatform.Feature( + feature_name='my_feature_id', + featurestore_id='my_featurestore_id', + entity_type_id='my_entity_type_id', + ) + my_feature.update( + description='update my description', + ) + + Args: + description (str): + Optional. Description of the Feature. + labels (Dict[str, str]): + Optional. The labels with user-defined + metadata to organize your Features. + Label keys and values can be no longer than 64 + characters (Unicode codepoints), can only + contain lowercase letters, numeric characters, + underscores and dashes. International characters + are allowed. + See https://goo.gl/xmQnxf for more information + on and examples of labels. No more than 64 user + labels can be associated with one Feature + (System labels are excluded)." + System reserved label keys are prefixed with + "aiplatform.googleapis.com/" and are immutable. + request_metadata (Sequence[Tuple[str, str]]): + Optional. Strings which should be sent along with the request as metadata. + + Returns: + Feature - The updated feature resource object. + """ + update_mask = list() + + if description: + update_mask.append("description") + + if labels: + utils.validate_labels(labels) + update_mask.append("labels") + + update_mask = field_mask_pb2.FieldMask(paths=update_mask) + + gapic_feature = gca_feature.Feature( + name=self.resource_name, description=description, labels=labels, + ) + + _LOGGER.log_action_start_against_resource( + "Updating", "feature", self, + ) + + update_feature_lro = self.api_client.update_feature( + feature=gapic_feature, update_mask=update_mask, metadata=request_metadata, + ) + + _LOGGER.log_action_started_against_resource_with_lro( + "Update", "feature", self.__class__, update_feature_lro + ) + + update_feature_lro.result() + + _LOGGER.log_action_completed_against_resource("feature", "updated", self) + + return self + + @classmethod + def list( + cls, + entity_type_name: str, + featurestore_id: Optional[str] = None, + filter: Optional[str] = None, + order_by: Optional[str] = None, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, + ) -> List["Feature"]: + """Lists existing managed feature resources in an entityType, given an entityType resource name or an entity_type ID. + + Example Usage: + + my_features = aiplatform.Feature.list( + entity_type_name='projects/123/locations/us-central1/featurestores/my_featurestore_id/\ + entityTypes/my_entity_type_id' + ) + or + my_features = aiplatform.Feature.list( + entity_type_name='my_entity_type_id', + featurestore_id='my_featurestore_id', + ) + + Args: + entity_type_name (str): + Required. A fully-qualified entityType resource name or an entity_type ID to list features in + Example: "projects/123/locations/us-central1/featurestores/my_featurestore_id/entityTypes/my_entity_type_id" + or "my_entity_type_id" when project and location are initialized or passed, with featurestore_id passed. + featurestore_id (str): + Optional. Featurestore ID to list features in, when entity_type_name is passed as entity_type ID. + filter (str): + Optional. Lists the Features that match the filter expression. The + following filters are supported: + + - ``value_type``: Supports = and != comparisons. + - ``create_time``: Supports =, !=, <, >, >=, and <= + comparisons. Values must be in RFC 3339 format. + - ``update_time``: Supports =, !=, <, >, >=, and <= + comparisons. Values must be in RFC 3339 format. + - ``labels``: Supports key-value equality as well as key + presence. + + Examples: + + - ``value_type = DOUBLE`` --> Features whose type is + DOUBLE. + - ``create_time > \"2020-01-31T15:30:00.000000Z\" OR update_time > \"2020-01-31T15:30:00.000000Z\"`` + --> EntityTypes created or updated after + 2020-01-31T15:30:00.000000Z. + - ``labels.active = yes AND labels.env = prod`` --> + Features having both (active: yes) and (env: prod) + labels. + - ``labels.env: *`` --> Any Feature which has a label with + 'env' as the key. + 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. Supported fields: + + - ``feature_id`` + - ``value_type`` + - ``create_time`` + - ``update_time`` + project (str): + Optional. Project to list features in. If not set, project + set in aiplatform.init will be used. + location (str): + Optional. Location to list features in. If not set, location + set in aiplatform.init will be used. + credentials (auth_credentials.Credentials): + Optional. Custom credentials to use to list features. Overrides + credentials set in aiplatform.init. + + Returns: + List[Feature] - A list of managed feature resource objects + """ + ( + featurestore_id, + entity_type_id, + ) = featurestore_utils.validate_and_get_entity_type_resource_ids( + entity_type_name=entity_type_name, featurestore_id=featurestore_id, + ) + + return cls._list( + filter=filter, + order_by=order_by, + project=project, + location=location, + credentials=credentials, + parent=utils.full_resource_name( + resource_name=entity_type_name, + resource_noun=f"featurestores/{featurestore_id}/entityTypes", + project=project, + location=location, + ), + ) + + @classmethod + def search( + cls, + query: Optional[str] = None, + page_size: Optional[int] = None, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, + ) -> List["Feature"]: + """Searches existing managed Feature resources. + + Example Usage: + + my_features = aiplatform.Feature.search() + + Args: + query (str): + Optional. Query string that is a conjunction of field-restricted + queries and/or field-restricted filters. + Field-restricted queries and filters can be combined + using ``AND`` to form a conjunction. + + A field query is in the form FIELD:QUERY. This + implicitly checks if QUERY exists as a substring within + Feature's FIELD. The QUERY and the FIELD are converted + to a sequence of words (i.e. tokens) for comparison. + This is done by: + + - Removing leading/trailing whitespace and tokenizing + the search value. Characters that are not one of + alphanumeric ``[a-zA-Z0-9]``, underscore ``_``, or + asterisk ``*`` are treated as delimiters for tokens. + ``*`` is treated as a wildcard that matches + characters within a token. + - Ignoring case. + - Prepending an asterisk to the first and appending an + asterisk to the last token in QUERY. + + A QUERY must be either a singular token or a phrase. A + phrase is one or multiple words enclosed in double + quotation marks ("). With phrases, the order of the + words is important. Words in the phrase must be matching + in order and consecutively. + + Supported FIELDs for field-restricted queries: + + - ``feature_id`` + - ``description`` + - ``entity_type_id`` + + Examples: + + - ``feature_id: foo`` --> Matches a Feature with ID + containing the substring ``foo`` (eg. ``foo``, + ``foofeature``, ``barfoo``). + - ``feature_id: foo*feature`` --> Matches a Feature + with ID containing the substring ``foo*feature`` (eg. + ``foobarfeature``). + - ``feature_id: foo AND description: bar`` --> Matches + a Feature with ID containing the substring ``foo`` + and description containing the substring ``bar``. + + Besides field queries, the following exact-match filters + are supported. The exact-match filters do not support + wildcards. Unlike field-restricted queries, exact-match + filters are case-sensitive. + + - ``feature_id``: Supports = comparisons. + - ``description``: Supports = comparisons. Multi-token + filters should be enclosed in quotes. + - ``entity_type_id``: Supports = comparisons. + - ``value_type``: Supports = and != comparisons. + - ``labels``: Supports key-value equality as well as + key presence. + - ``featurestore_id``: Supports = comparisons. + + Examples: + + - ``description = "foo bar"`` --> Any Feature with + description exactly equal to ``foo bar`` + - ``value_type = DOUBLE`` --> Features whose type is + DOUBLE. + - ``labels.active = yes AND labels.env = prod`` --> + Features having both (active: yes) and (env: prod) + labels. + - ``labels.env: *`` --> Any Feature which has a label + with ``env`` as the key. + + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + page_size (int): + Optional. The maximum number of Features to return. The + service may return fewer than this value. If + unspecified, at most 100 Features will be + returned. The maximum value is 100; any value + greater than 100 will be coerced to 100. + project (str): + Optional. Project to list features in. If not set, project + set in aiplatform.init will be used. + location (str): + Optional. Location to list features in. If not set, location + set in aiplatform.init will be used. + credentials (auth_credentials.Credentials): + Optional. Custom credentials to use to list features. Overrides + credentials set in aiplatform.init. + + Returns: + List[Feature] - A list of managed feature resource objects + """ + resource = cls._empty_constructor( + project=project, location=location, credentials=credentials + ) + + # Fetch credentials once and re-use for all `_empty_constructor()` calls + creds = resource.credentials + + search_features_request = { + "location": initializer.global_config.common_location_path( + project=project, location=location + ), + "query": query, + } + + if page_size: + search_features_request["page_size"] = page_size + + resource_list = ( + resource.api_client.search_features(request=search_features_request) or [] + ) + + return [ + cls._construct_sdk_resource_from_gapic( + gapic_resource, project=project, location=location, credentials=creds + ) + for gapic_resource in resource_list + ] diff --git a/google/cloud/aiplatform/featurestore/featurestore.py b/google/cloud/aiplatform/featurestore/featurestore.py new file mode 100644 index 0000000000..d3bb0a0c11 --- /dev/null +++ b/google/cloud/aiplatform/featurestore/featurestore.py @@ -0,0 +1,324 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +from typing import Dict, List, Optional, Sequence, Tuple + +from google.auth import credentials as auth_credentials +from google.protobuf import field_mask_pb2 + +from google.cloud.aiplatform import base +from google.cloud.aiplatform.compat.types import featurestore as gca_featurestore +from google.cloud.aiplatform import featurestore +from google.cloud.aiplatform import utils +from google.cloud.aiplatform.utils import featurestore_utils + +_LOGGER = base.Logger(__name__) + + +class Featurestore(base.VertexAiResourceNounWithFutureManager): + """Managed featurestore resource for Vertex AI.""" + + client_class = utils.FeaturestoreClientWithOverride + + _is_client_prediction_client = False + _resource_noun = "featurestores" + _getter_method = "get_featurestore" + _list_method = "list_featurestores" + _delete_method = "delete_featurestore" + + def __init__( + self, + featurestore_name: str, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, + ): + """Retrieves an existing managed featurestore given a featurestore resource name or a featurestore ID. + + Example Usage: + + my_featurestore = aiplatform.Featurestore( + featurestore_name='projects/123/locations/us-central1/featurestores/my_featurestore_id' + ) + or + my_featurestore = aiplatform.Featurestore( + featurestore_name='my_featurestore_id' + ) + + Args: + featurestore_name (str): + Required. A fully-qualified featurestore resource name or a featurestore ID. + Example: "projects/123/locations/us-central1/featurestores/my_featurestore_id" + or "my_featurestore_id" when project and location are initialized or passed. + project (str): + Optional. Project to retrieve featurestore from. If not set, project + set in aiplatform.init will be used. + location (str): + Optional. Location to retrieve featurestore from. If not set, location + set in aiplatform.init will be used. + credentials (auth_credentials.Credentials): + Optional. Custom credentials to use to retrieve this Featurestore. Overrides + credentials set in aiplatform.init. + """ + + super().__init__( + project=project, + location=location, + credentials=credentials, + resource_name=featurestore_name, + ) + self._gca_resource = self._get_gca_resource(resource_name=featurestore_name) + + def get_entity_type(self, entity_type_id: str) -> "featurestore.EntityType": + """Retrieves an existing managed entityType in this Featurestore. + + Args: + entity_type_id (str): + Required. The managed entityType resource ID in this Featurestore. + Returns: + featurestore.EntityType - The managed entityType resource object. + """ + featurestore_name_components = featurestore_utils.CompatFeaturestoreServiceClient.parse_featurestore_path( + path=self.resource_name + ) + + return featurestore.EntityType( + entity_type_name=featurestore_utils.CompatFeaturestoreServiceClient.entity_type_path( + project=featurestore_name_components["project"], + location=featurestore_name_components["location"], + featurestore=featurestore_name_components["featurestore"], + entity_type=entity_type_id, + ) + ) + + def update( + self, + labels: Optional[Dict[str, str]] = None, + request_metadata: Optional[Sequence[Tuple[str, str]]] = (), + ) -> "Featurestore": + """Updates an existing managed featurestore resource. + + Example Usage: + + my_featurestore = aiplatform.Featurestore( + featurestore_name='my_featurestore_id', + ) + my_featurestore.update( + labels={'update my key': 'update my value'}, + ) + + Args: + labels (Dict[str, str]): + Optional. The labels with user-defined + metadata to organize your Featurestores. + Label keys and values can be no longer than 64 + characters (Unicode codepoints), can only + contain lowercase letters, numeric characters, + underscores and dashes. International characters + are allowed. + See https://goo.gl/xmQnxf for more information + on and examples of labels. No more than 64 user + labels can be associated with one Feature + (System labels are excluded)." + System reserved label keys are prefixed with + "aiplatform.googleapis.com/" and are immutable. + request_metadata (Sequence[Tuple[str, str]]): + Optional. Strings which should be sent along with the request as metadata. + + Returns: + Featurestore - The updated featurestore resource object. + """ + + return self._update(labels=labels, request_metadata=request_metadata) + + # TODO(b/206818784): Add enable_online_store and disable_online_store methods + def update_online_store( + self, + fixed_node_count: int, + request_metadata: Optional[Sequence[Tuple[str, str]]] = (), + ) -> "Featurestore": + """Updates the online store of an existing managed featurestore resource. + + Example Usage: + + my_featurestore = aiplatform.Featurestore( + featurestore_name='my_featurestore_id', + ) + my_featurestore.update_online_store( + fixed_node_count=2, + ) + + Args: + fixed_node_count (int): + Required. Config for online serving resources, can only update the node count to >= 1. + request_metadata (Sequence[Tuple[str, str]]): + Optional. Strings which should be sent along with the request as metadata. + + Returns: + Featurestore - The updated featurestore resource object. + """ + return self._update( + fixed_node_count=fixed_node_count, request_metadata=request_metadata + ) + + def _update( + self, + labels: Optional[Dict[str, str]] = None, + fixed_node_count: Optional[int] = None, + request_metadata: Optional[Sequence[Tuple[str, str]]] = (), + ) -> "Featurestore": + """Updates an existing managed featurestore resource. + + Args: + labels (Dict[str, str]): + Optional. The labels with user-defined + metadata to organize your Featurestores. + Label keys and values can be no longer than 64 + characters (Unicode codepoints), can only + contain lowercase letters, numeric characters, + underscores and dashes. International characters + are allowed. + See https://goo.gl/xmQnxf for more information + on and examples of labels. No more than 64 user + labels can be associated with one Feature + (System labels are excluded)." + System reserved label keys are prefixed with + "aiplatform.googleapis.com/" and are immutable. + fixed_node_count (int): + Optional. Config for online serving resources, can only update the node count to >= 1. + request_metadata (Sequence[Tuple[str, str]]): + Optional. Strings which should be sent along with the request as metadata. + + Returns: + Featurestore - The updated featurestore resource object. + """ + update_mask = list() + + if labels: + utils.validate_labels(labels) + update_mask.append("labels") + + if fixed_node_count is not None: + update_mask.append("online_serving_config.fixed_node_count") + + update_mask = field_mask_pb2.FieldMask(paths=update_mask) + + gapic_featurestore = gca_featurestore.Featurestore( + name=self.resource_name, + labels=labels, + online_serving_config=gca_featurestore.Featurestore.OnlineServingConfig( + fixed_node_count=fixed_node_count + ), + ) + + _LOGGER.log_action_start_against_resource( + "Updating", "featurestore", self, + ) + + update_featurestore_lro = self.api_client.update_featurestore( + featurestore=gapic_featurestore, + update_mask=update_mask, + metadata=request_metadata, + ) + + _LOGGER.log_action_started_against_resource_with_lro( + "Update", "featurestore", self.__class__, update_featurestore_lro + ) + + update_featurestore_lro.result() + + _LOGGER.log_action_completed_against_resource("featurestore", "updated", self) + + return self + + def list_entity_types( + self, filter: Optional[str] = None, order_by: Optional[str] = None, + ) -> List["featurestore.EntityType"]: + """Lists existing managed entityType resources in this Featurestore. + + Example Usage: + + my_featurestore = aiplatform.Featurestore( + featurestore_name='my_featurestore_id', + ) + my_featurestore.list_entity_types() + + Args: + filter (str): + Optional. Lists the EntityTypes that match the filter expression. The + following filters are supported: + + - ``create_time``: Supports ``=``, ``!=``, ``<``, ``>``, + ``>=``, and ``<=`` comparisons. Values must be in RFC + 3339 format. + - ``update_time``: Supports ``=``, ``!=``, ``<``, ``>``, + ``>=``, and ``<=`` comparisons. Values must be in RFC + 3339 format. + - ``labels``: Supports key-value equality as well as key + presence. + + Examples: + + - ``create_time > \"2020-01-31T15:30:00.000000Z\" OR update_time > \"2020-01-31T15:30:00.000000Z\"`` + --> EntityTypes created or updated after + 2020-01-31T15:30:00.000000Z. + - ``labels.active = yes AND labels.env = prod`` --> + EntityTypes having both (active: yes) and (env: prod) + labels. + - ``labels.env: *`` --> Any EntityType which has a label + with 'env' as the key. + 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. + + Supported fields: + + - ``entity_type_id`` + - ``create_time`` + - ``update_time`` + + Returns: + List[featurestore.EntityType] - A list of managed entityType resource objects. + """ + return featurestore.EntityType.list( + featurestore_name=self.resource_name, filter=filter, order_by=order_by, + ) + + @base.optional_sync() + def delete_entity_types( + self, entity_type_ids: List[str], sync: bool = True, + ) -> None: + """Deletes entity_type resources in this Featurestore given their entity_type IDs. + WARNING: This deletion is permanent. + + Args: + entity_type_ids (List[str]): + Required. The list of entity_type IDs to be deleted. + sync (bool): + Optional. Whether to execute this deletion synchronously. If False, this method + will be executed in concurrent Future and any downstream object will + be immediately returned and synced when the Future has completed. + """ + entity_types = [] + for entity_type_id in entity_type_ids: + entity_type = self.get_entity_type(entity_type_id=entity_type_id) + entity_type.delete(sync=False) + entity_types.append(entity_type) + + for entity_type in entity_types: + entity_type.wait() diff --git a/google/cloud/aiplatform/gapic/schema/__init__.py b/google/cloud/aiplatform/gapic/schema/__init__.py index e726749c77..5d31a70f1f 100644 --- a/google/cloud/aiplatform/gapic/schema/__init__.py +++ b/google/cloud/aiplatform/gapic/schema/__init__.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from google.cloud.aiplatform.helpers import _decorators +from google.cloud.aiplatform.utils.enhanced_library import _decorators from google.cloud.aiplatform.v1.schema import predict from google.cloud.aiplatform.v1.schema import trainingjob from google.cloud.aiplatform.v1beta1.schema import predict as predict_v1beta1 diff --git a/google/cloud/aiplatform/helpers/__init__.py b/google/cloud/aiplatform/helpers/__init__.py index 3f031f2bb4..e5fa8f665d 100644 --- a/google/cloud/aiplatform/helpers/__init__.py +++ b/google/cloud/aiplatform/helpers/__init__.py @@ -1,3 +1,21 @@ -from google.cloud.aiplatform.helpers import value_converter +# 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. -__all__ = (value_converter,) +from google.cloud.aiplatform.helpers import container_uri_builders + +get_prebuilt_prediction_container_uri = ( + container_uri_builders.get_prebuilt_prediction_container_uri +) + +__all__ = "get_prebuilt_prediction_container_uri" diff --git a/google/cloud/aiplatform/helpers/container_uri_builders.py b/google/cloud/aiplatform/helpers/container_uri_builders.py new file mode 100644 index 0000000000..6b49d3e230 --- /dev/null +++ b/google/cloud/aiplatform/helpers/container_uri_builders.py @@ -0,0 +1,109 @@ +# 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. + +from typing import Optional + +from google.cloud.aiplatform.constants import prediction +from google.cloud.aiplatform import initializer + + +def get_prebuilt_prediction_container_uri( + framework: str, + framework_version: str, + region: Optional[str] = None, + accelerator: str = "cpu", +) -> str: + """ + Get a Vertex AI pre-built prediction Docker container URI for + a given framework, version, region, and accelerator use. + + Example usage: + ``` + uri = aiplatform.helpers.get_prebuilt_prediction_container_uri( + framework="tensorflow", + framework_version="2.6", + accelerator="gpu" + ) + + model = aiplatform.Model.upload( + display_name="boston_housing_", + artifact_uri="gs://my-bucket/my-model/", + serving_container_image_uri=uri + ) + ``` + + Args: + framework (str): + Required. The ML framework of the pre-built container. For example, + `"tensorflow"`, `"xgboost"`, or `"sklearn"` + framework_version (str): + Required. The version of the specified ML framework as a string. + region (str): + Optional. AI region or multi-region. Used to select the correct + Artifact Registry multi-region repository and reduce latency. + Must start with `"us"`, `"asia"` or `"europe"`. + Default is location set by `aiplatform.init()`. + accelerator (str): + Optional. The type of accelerator support provided by container. For + example: `"cpu"` or `"gpu"` + Default is `"cpu"`. + + Returns: + uri (str): + A Vertex AI prediction container URI + + Raises: + ValueError: If containers for provided framework are unavailable or the + container does not support the specified version, accelerator, or region. + """ + URI_MAP = prediction._SERVING_CONTAINER_URI_MAP + DOCS_URI_MESSAGE = ( + f"See {prediction._SERVING_CONTAINER_DOCUMENTATION_URL} " + "for complete list of supported containers" + ) + + # If region not provided, use initializer location + region = region or initializer.global_config.location + region = region.split("-", 1)[0] + framework = framework.lower() + + if not URI_MAP.get(region): + raise ValueError( + f"Unsupported container region `{region}`, supported regions are " + f"{', '.join(URI_MAP.keys())}. " + f"{DOCS_URI_MESSAGE}" + ) + + if not URI_MAP[region].get(framework): + raise ValueError( + f"No containers found for framework `{framework}`. Supported frameworks are " + f"{', '.join(URI_MAP[region].keys())} {DOCS_URI_MESSAGE}" + ) + + if not URI_MAP[region][framework].get(accelerator): + raise ValueError( + f"{framework} containers do not support `{accelerator}` accelerator. Supported accelerators " + f"are {', '.join(URI_MAP[region][framework].keys())}. {DOCS_URI_MESSAGE}" + ) + + final_uri = URI_MAP[region][framework][accelerator].get(framework_version) + + if not final_uri: + raise ValueError( + f"No serving container for `{framework}` version `{framework_version}` " + f"with accelerator `{accelerator}` found. Supported versions " + f"include {', '.join(URI_MAP[region][framework][accelerator].keys())}. {DOCS_URI_MESSAGE}" + ) + + return final_uri diff --git a/google/cloud/aiplatform/initializer.py b/google/cloud/aiplatform/initializer.py index ea1a51c8a7..00f6b19b40 100644 --- a/google/cloud/aiplatform/initializer.py +++ b/google/cloud/aiplatform/initializer.py @@ -29,7 +29,7 @@ from google.auth.exceptions import GoogleAuthError from google.cloud.aiplatform import compat -from google.cloud.aiplatform import constants +from google.cloud.aiplatform.constants import base as constants from google.cloud.aiplatform import utils from google.cloud.aiplatform.metadata import metadata diff --git a/google/cloud/aiplatform/jobs.py b/google/cloud/aiplatform/jobs.py index c1ba9739cc..57958fc779 100644 --- a/google/cloud/aiplatform/jobs.py +++ b/google/cloud/aiplatform/jobs.py @@ -35,16 +35,14 @@ batch_prediction_job as gca_bp_job_compat, completion_stats as gca_completion_stats, custom_job as gca_custom_job_compat, - custom_job_v1beta1 as gca_custom_job_v1beta1, explanation as gca_explanation_compat, io as gca_io_compat, job_state as gca_job_state, hyperparameter_tuning_job as gca_hyperparameter_tuning_job_compat, - hyperparameter_tuning_job_v1beta1 as gca_hyperparameter_tuning_job_v1beta1, machine_resources as gca_machine_resources_compat, study as gca_study_compat, ) -from google.cloud.aiplatform import constants +from google.cloud.aiplatform.constants import base as constants from google.cloud.aiplatform import initializer from google.cloud.aiplatform import hyperparameter_tuning from google.cloud.aiplatform import utils @@ -1388,17 +1386,11 @@ def run( self._gca_resource.job_spec.enable_web_access = enable_web_access if tensorboard: - v1beta1_gca_resource = gca_custom_job_v1beta1.CustomJob() - v1beta1_gca_resource._pb.MergeFromString( - self._gca_resource._pb.SerializeToString() - ) - self._gca_resource = v1beta1_gca_resource self._gca_resource.job_spec.tensorboard = tensorboard _LOGGER.log_create_with_lro(self.__class__) - version = "v1beta1" if tensorboard else "v1" - self._gca_resource = self.api_client.select_version(version).create_custom_job( + self._gca_resource = self.api_client.create_custom_job( parent=self._parent, custom_job=self._gca_resource ) @@ -1773,21 +1765,11 @@ def run( self._gca_resource.trial_job_spec.enable_web_access = enable_web_access if tensorboard: - v1beta1_gca_resource = ( - gca_hyperparameter_tuning_job_v1beta1.HyperparameterTuningJob() - ) - v1beta1_gca_resource._pb.MergeFromString( - self._gca_resource._pb.SerializeToString() - ) - self._gca_resource = v1beta1_gca_resource self._gca_resource.trial_job_spec.tensorboard = tensorboard _LOGGER.log_create_with_lro(self.__class__) - version = "v1beta1" if tensorboard else "v1" - self._gca_resource = self.api_client.select_version( - version - ).create_hyperparameter_tuning_job( + self._gca_resource = self.api_client.create_hyperparameter_tuning_job( parent=self._parent, hyperparameter_tuning_job=self._gca_resource ) diff --git a/google/cloud/aiplatform/models.py b/google/cloud/aiplatform/models.py index 2ce48adc53..87af6b16bf 100644 --- a/google/cloud/aiplatform/models.py +++ b/google/cloud/aiplatform/models.py @@ -14,7 +14,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import pathlib import proto +import re +import shutil +import tempfile from typing import Dict, List, NamedTuple, Optional, Sequence, Tuple, Union from google.api_core import operation @@ -28,6 +32,7 @@ from google.cloud.aiplatform import jobs from google.cloud.aiplatform import models from google.cloud.aiplatform import utils +from google.cloud.aiplatform.utils import gcs_utils from google.cloud.aiplatform.compat.services import endpoint_service_client @@ -49,6 +54,15 @@ _LOGGER = base.Logger(__name__) +_SUPPORTED_MODEL_FILE_NAMES = [ + "model.pkl", + "model.joblib", + "model.bst", + "saved_model.pb", + "saved_model.pbtxt", +] + + class Prediction(NamedTuple): """Prediction class envelopes returned Model predictions and the Model id. @@ -1492,6 +1506,7 @@ def upload( credentials: Optional[auth_credentials.Credentials] = None, labels: Optional[Dict[str, str]] = None, encryption_spec_key_name: Optional[str] = None, + staging_bucket: Optional[str] = None, sync=True, ) -> "Model": """Uploads a model and returns a Model representing the uploaded Model @@ -1635,11 +1650,15 @@ def upload( If set, this Model and all sub-resources of this Model will be secured by this key. Overrides encryption_spec_key_name set in aiplatform.init. + staging_bucket (str): + Optional. Bucket to stage local model artifacts. Overrides + staging_bucket set in aiplatform.init. Returns: model: Instantiated representation of the uploaded model resource. Raises: ValueError: If only `explanation_metadata` or `explanation_parameters` is specified. + Also if model directory does not contain a supported model file. """ utils.validate_display_name(display_name) if labels: @@ -1697,6 +1716,36 @@ def upload( encryption_spec=encryption_spec, ) + if artifact_uri and not artifact_uri.startswith("gs://"): + model_dir = pathlib.Path(artifact_uri) + # Validating the model directory + if not model_dir.exists(): + raise ValueError(f"artifact_uri path does not exist: '{artifact_uri}'") + PREBUILT_IMAGE_RE = "(us|europe|asia)-docker.pkg.dev/vertex-ai/prediction/" + if re.match(PREBUILT_IMAGE_RE, serving_container_image_uri): + if not model_dir.is_dir(): + raise ValueError( + f"artifact_uri path must be a directory: '{artifact_uri}' when using prebuilt image '{serving_container_image_uri}'" + ) + if not any( + (model_dir / file_name).exists() + for file_name in _SUPPORTED_MODEL_FILE_NAMES + ): + raise ValueError( + "artifact_uri directory does not contain any supported model files. " + f"When using a prebuilt serving image, the upload method only supports the following model files: '{_SUPPORTED_MODEL_FILE_NAMES}'" + ) + + # Uploading the model + staged_data_uri = gcs_utils.stage_local_data_in_gcs( + data_path=str(model_dir), + staging_gcs_dir=staging_bucket, + project=project, + location=location, + credentials=credentials, + ) + artifact_uri = staged_data_uri + if artifact_uri: managed_model.artifact_uri = artifact_uri @@ -2389,3 +2438,558 @@ def export_model( _LOGGER.log_action_completed_against_resource("model", "exported", self) return json_format.MessageToDict(operation_future.metadata.output_info._pb) + + @classmethod + @base.optional_sync() + def upload_xgboost_model_file( + cls, + model_file_path: str, + xgboost_version: str = "1.4", + display_name: str = "XGBoost model", + description: Optional[str] = None, + instance_schema_uri: Optional[str] = None, + parameters_schema_uri: Optional[str] = None, + prediction_schema_uri: Optional[str] = None, + explanation_metadata: Optional[explain.ExplanationMetadata] = None, + explanation_parameters: Optional[explain.ExplanationParameters] = None, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, + labels: Optional[Dict[str, str]] = None, + encryption_spec_key_name: Optional[str] = None, + staging_bucket: Optional[str] = None, + sync=True, + ) -> "Model": + """Uploads a model and returns a Model representing the uploaded Model + resource. + + Note: This function is *experimental* and can be changed in the future. + + Example usage:: + + my_model = Model.upload_xgboost_model_file( + model_file_path="iris.xgboost_model.bst" + ) + + Args: + model_file_path (str): Required. Local file path of the model. + xgboost_version (str): Optional. The version of the XGBoost serving container. + Supported versions: ["0.82", "0.90", "1.1", "1.2", "1.3", "1.4"]. + If the version is not specified, the latest version is used. + display_name (str): + Optional. The display name of the Model. The name can be up to 128 + characters long and can be consist of any UTF-8 characters. + description (str): + The description of the model. + instance_schema_uri (str): + Optional. Points to a YAML file stored on Google Cloud + Storage describing the format of a single instance, which + are used in + ``PredictRequest.instances``, + ``ExplainRequest.instances`` + and + ``BatchPredictionJob.input_config``. + The schema is defined as an OpenAPI 3.0.2 `Schema + Object `__. + AutoML Models always have this field populated by AI + Platform. Note: The URI given on output will be immutable + and probably different, including the URI scheme, than the + one given on input. The output URI will point to a location + where the user only has a read access. + parameters_schema_uri (str): + Optional. Points to a YAML file stored on Google Cloud + Storage describing the parameters of prediction and + explanation via + ``PredictRequest.parameters``, + ``ExplainRequest.parameters`` + and + ``BatchPredictionJob.model_parameters``. + The schema is defined as an OpenAPI 3.0.2 `Schema + Object `__. + AutoML Models always have this field populated by AI + Platform, if no parameters are supported it is set to an + empty string. Note: The URI given on output will be + immutable and probably different, including the URI scheme, + than the one given on input. The output URI will point to a + location where the user only has a read access. + prediction_schema_uri (str): + Optional. Points to a YAML file stored on Google Cloud + Storage describing the format of a single prediction + produced by this Model, which are returned via + ``PredictResponse.predictions``, + ``ExplainResponse.explanations``, + and + ``BatchPredictionJob.output_config``. + The schema is defined as an OpenAPI 3.0.2 `Schema + Object `__. + AutoML Models always have this field populated by AI + Platform. Note: The URI given on output will be immutable + and probably different, including the URI scheme, than the + one given on input. The output URI will point to a location + where the user only has a read access. + explanation_metadata (explain.ExplanationMetadata): + Optional. Metadata describing the Model's input and output for explanation. + Both `explanation_metadata` and `explanation_parameters` must be + passed together when used. For more details, see + `Ref docs ` + explanation_parameters (explain.ExplanationParameters): + Optional. Parameters to configure explaining for Model's predictions. + For more details, see `Ref docs ` + project: Optional[str]=None, + Project to upload this model to. Overrides project set in + aiplatform.init. + location: Optional[str]=None, + Location to upload this model to. Overrides location set in + aiplatform.init. + credentials: Optional[auth_credentials.Credentials]=None, + Custom credentials to use to upload this model. Overrides credentials + set in aiplatform.init. + labels (Dict[str, str]): + Optional. The labels with user-defined metadata to + organize your Models. + Label keys and values can be no longer than 64 + characters (Unicode codepoints), can only + contain lowercase letters, numeric characters, + underscores and dashes. International characters + are allowed. + See https://goo.gl/xmQnxf for more information + and examples of labels. + encryption_spec_key_name (Optional[str]): + Optional. The Cloud KMS resource identifier of the customer + managed encryption key used to protect the model. Has the + form: + ``projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key``. + The key needs to be in the same region as where the compute + resource is created. + + If set, this Model and all sub-resources of this Model will be secured by this key. + + Overrides encryption_spec_key_name set in aiplatform.init. + staging_bucket (str): + Optional. Bucket to stage local model artifacts. Overrides + staging_bucket set in aiplatform.init. + Returns: + model: Instantiated representation of the uploaded model resource. + Raises: + ValueError: If only `explanation_metadata` or `explanation_parameters` + is specified. + Also if model directory does not contain a supported model file. + """ + XGBOOST_SUPPORTED_MODEL_FILE_EXTENSIONS = [ + ".pkl", + ".joblib", + ".bst", + ] + + container_image_uri = aiplatform.helpers.get_prebuilt_prediction_container_uri( + region=location, + framework="xgboost", + framework_version=xgboost_version, + accelerator="cpu", + ) + + model_file_path_obj = pathlib.Path(model_file_path) + if not model_file_path_obj.is_file(): + raise ValueError( + f"model_file_path path must point to a file: '{model_file_path}'" + ) + + model_file_extension = model_file_path_obj.suffix + if model_file_extension not in XGBOOST_SUPPORTED_MODEL_FILE_EXTENSIONS: + _LOGGER.warning( + f"Only the following XGBoost model file extensions are currently supported: '{XGBOOST_SUPPORTED_MODEL_FILE_EXTENSIONS}'" + ) + _LOGGER.warning( + "Treating the model file as a binary serialized XGBoost Booster." + ) + model_file_extension = ".bst" + + # Preparing model directory + # We cannot clean up the directory immediately after calling Model.upload since + # that call may be asynchronous and return before the model file has been read. + # To work around this, we make this method asynchronous (decorate with @base.optional_sync) + # but call Model.upload with sync=True. + with tempfile.TemporaryDirectory() as prepared_model_dir: + prepared_model_file_path = pathlib.Path(prepared_model_dir) / ( + "model" + model_file_extension + ) + shutil.copy(model_file_path_obj, prepared_model_file_path) + + return cls.upload( + serving_container_image_uri=container_image_uri, + artifact_uri=prepared_model_dir, + display_name=display_name, + description=description, + instance_schema_uri=instance_schema_uri, + parameters_schema_uri=parameters_schema_uri, + prediction_schema_uri=prediction_schema_uri, + explanation_metadata=explanation_metadata, + explanation_parameters=explanation_parameters, + project=project, + location=location, + credentials=credentials, + labels=labels, + encryption_spec_key_name=encryption_spec_key_name, + staging_bucket=staging_bucket, + sync=True, + ) + + @classmethod + @base.optional_sync() + def upload_scikit_learn_model_file( + cls, + model_file_path: str, + sklearn_version: str = "1.0", + display_name: str = "Scikit-learn model", + description: Optional[str] = None, + instance_schema_uri: Optional[str] = None, + parameters_schema_uri: Optional[str] = None, + prediction_schema_uri: Optional[str] = None, + explanation_metadata: Optional[explain.ExplanationMetadata] = None, + explanation_parameters: Optional[explain.ExplanationParameters] = None, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, + labels: Optional[Dict[str, str]] = None, + encryption_spec_key_name: Optional[str] = None, + staging_bucket: Optional[str] = None, + sync=True, + ) -> "Model": + """Uploads a model and returns a Model representing the uploaded Model + resource. + + Note: This function is *experimental* and can be changed in the future. + + Example usage:: + + my_model = Model.upload_scikit_learn_model_file( + model_file_path="iris.sklearn_model.joblib" + ) + + Args: + model_file_path (str): Required. Local file path of the model. + sklearn_version (str): + Optional. The version of the Scikit-learn serving container. + Supported versions: ["0.20", "0.22", "0.23", "0.24", "1.0"]. + If the version is not specified, the latest version is used. + display_name (str): + Optional. The display name of the Model. The name can be up to 128 + characters long and can be consist of any UTF-8 characters. + description (str): + The description of the model. + instance_schema_uri (str): + Optional. Points to a YAML file stored on Google Cloud + Storage describing the format of a single instance, which + are used in + ``PredictRequest.instances``, + ``ExplainRequest.instances`` + and + ``BatchPredictionJob.input_config``. + The schema is defined as an OpenAPI 3.0.2 `Schema + Object `__. + AutoML Models always have this field populated by AI + Platform. Note: The URI given on output will be immutable + and probably different, including the URI scheme, than the + one given on input. The output URI will point to a location + where the user only has a read access. + parameters_schema_uri (str): + Optional. Points to a YAML file stored on Google Cloud + Storage describing the parameters of prediction and + explanation via + ``PredictRequest.parameters``, + ``ExplainRequest.parameters`` + and + ``BatchPredictionJob.model_parameters``. + The schema is defined as an OpenAPI 3.0.2 `Schema + Object `__. + AutoML Models always have this field populated by AI + Platform, if no parameters are supported it is set to an + empty string. Note: The URI given on output will be + immutable and probably different, including the URI scheme, + than the one given on input. The output URI will point to a + location where the user only has a read access. + prediction_schema_uri (str): + Optional. Points to a YAML file stored on Google Cloud + Storage describing the format of a single prediction + produced by this Model, which are returned via + ``PredictResponse.predictions``, + ``ExplainResponse.explanations``, + and + ``BatchPredictionJob.output_config``. + The schema is defined as an OpenAPI 3.0.2 `Schema + Object `__. + AutoML Models always have this field populated by AI + Platform. Note: The URI given on output will be immutable + and probably different, including the URI scheme, than the + one given on input. The output URI will point to a location + where the user only has a read access. + explanation_metadata (explain.ExplanationMetadata): + Optional. Metadata describing the Model's input and output for explanation. + Both `explanation_metadata` and `explanation_parameters` must be + passed together when used. For more details, see + `Ref docs ` + explanation_parameters (explain.ExplanationParameters): + Optional. Parameters to configure explaining for Model's predictions. + For more details, see `Ref docs ` + project: Optional[str]=None, + Project to upload this model to. Overrides project set in + aiplatform.init. + location: Optional[str]=None, + Location to upload this model to. Overrides location set in + aiplatform.init. + credentials: Optional[auth_credentials.Credentials]=None, + Custom credentials to use to upload this model. Overrides credentials + set in aiplatform.init. + labels (Dict[str, str]): + Optional. The labels with user-defined metadata to + organize your Models. + Label keys and values can be no longer than 64 + characters (Unicode codepoints), can only + contain lowercase letters, numeric characters, + underscores and dashes. International characters + are allowed. + See https://goo.gl/xmQnxf for more information + and examples of labels. + encryption_spec_key_name (Optional[str]): + Optional. The Cloud KMS resource identifier of the customer + managed encryption key used to protect the model. Has the + form: + ``projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key``. + The key needs to be in the same region as where the compute + resource is created. + + If set, this Model and all sub-resources of this Model will be secured by this key. + + Overrides encryption_spec_key_name set in aiplatform.init. + staging_bucket (str): + Optional. Bucket to stage local model artifacts. Overrides + staging_bucket set in aiplatform.init. + Returns: + model: Instantiated representation of the uploaded model resource. + Raises: + ValueError: If only `explanation_metadata` or `explanation_parameters` + is specified. + Also if model directory does not contain a supported model file. + """ + SKLEARN_SUPPORTED_MODEL_FILE_EXTENSIONS = [ + ".pkl", + ".joblib", + ] + + container_image_uri = aiplatform.helpers.get_prebuilt_prediction_container_uri( + region=location, + framework="sklearn", + framework_version=sklearn_version, + accelerator="cpu", + ) + + model_file_path_obj = pathlib.Path(model_file_path) + if not model_file_path_obj.is_file(): + raise ValueError( + f"model_file_path path must point to a file: '{model_file_path}'" + ) + + model_file_extension = model_file_path_obj.suffix + if model_file_extension not in SKLEARN_SUPPORTED_MODEL_FILE_EXTENSIONS: + _LOGGER.warning( + f"Only the following Scikit-learn model file extensions are currently supported: '{SKLEARN_SUPPORTED_MODEL_FILE_EXTENSIONS}'" + ) + _LOGGER.warning( + "Treating the model file as a pickle serialized Scikit-learn model." + ) + model_file_extension = ".pkl" + + # Preparing model directory + # We cannot clean up the directory immediately after calling Model.upload since + # that call may be asynchronous and return before the model file has been read. + # To work around this, we make this method asynchronous (decorate with @base.optional_sync) + # but call Model.upload with sync=True. + with tempfile.TemporaryDirectory() as prepared_model_dir: + prepared_model_file_path = pathlib.Path(prepared_model_dir) / ( + "model" + model_file_extension + ) + shutil.copy(model_file_path_obj, prepared_model_file_path) + + return cls.upload( + serving_container_image_uri=container_image_uri, + artifact_uri=prepared_model_dir, + display_name=display_name, + description=description, + instance_schema_uri=instance_schema_uri, + parameters_schema_uri=parameters_schema_uri, + prediction_schema_uri=prediction_schema_uri, + explanation_metadata=explanation_metadata, + explanation_parameters=explanation_parameters, + project=project, + location=location, + credentials=credentials, + labels=labels, + encryption_spec_key_name=encryption_spec_key_name, + staging_bucket=staging_bucket, + sync=True, + ) + + @classmethod + def upload_tensorflow_saved_model( + cls, + saved_model_dir: str, + tensorflow_version: str = "2.7", + use_gpu: bool = False, + display_name: str = "Tensorflow model", + description: Optional[str] = None, + instance_schema_uri: Optional[str] = None, + parameters_schema_uri: Optional[str] = None, + prediction_schema_uri: Optional[str] = None, + explanation_metadata: Optional[explain.ExplanationMetadata] = None, + explanation_parameters: Optional[explain.ExplanationParameters] = None, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, + labels: Optional[Dict[str, str]] = None, + encryption_spec_key_name: Optional[str] = None, + staging_bucket: Optional[str] = None, + sync=True, + ) -> "Model": + """Uploads a model and returns a Model representing the uploaded Model + resource. + + Note: This function is *experimental* and can be changed in the future. + + Example usage:: + + my_model = Model.upload_scikit_learn_model_file( + model_file_path="iris.tensorflow_model.SavedModel" + ) + + Args: + saved_model_dir (str): Required. + Local directory of the Tensorflow SavedModel. + tensorflow_version (str): + Optional. The version of the Tensorflow serving container. + Supported versions: ["0.15", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7"]. + If the version is not specified, the latest version is used. + use_gpu (bool): Whether to use GPU for model serving. + display_name (str): + Optional. The display name of the Model. The name can be up to 128 + characters long and can be consist of any UTF-8 characters. + description (str): + The description of the model. + instance_schema_uri (str): + Optional. Points to a YAML file stored on Google Cloud + Storage describing the format of a single instance, which + are used in + ``PredictRequest.instances``, + ``ExplainRequest.instances`` + and + ``BatchPredictionJob.input_config``. + The schema is defined as an OpenAPI 3.0.2 `Schema + Object `__. + AutoML Models always have this field populated by AI + Platform. Note: The URI given on output will be immutable + and probably different, including the URI scheme, than the + one given on input. The output URI will point to a location + where the user only has a read access. + parameters_schema_uri (str): + Optional. Points to a YAML file stored on Google Cloud + Storage describing the parameters of prediction and + explanation via + ``PredictRequest.parameters``, + ``ExplainRequest.parameters`` + and + ``BatchPredictionJob.model_parameters``. + The schema is defined as an OpenAPI 3.0.2 `Schema + Object `__. + AutoML Models always have this field populated by AI + Platform, if no parameters are supported it is set to an + empty string. Note: The URI given on output will be + immutable and probably different, including the URI scheme, + than the one given on input. The output URI will point to a + location where the user only has a read access. + prediction_schema_uri (str): + Optional. Points to a YAML file stored on Google Cloud + Storage describing the format of a single prediction + produced by this Model, which are returned via + ``PredictResponse.predictions``, + ``ExplainResponse.explanations``, + and + ``BatchPredictionJob.output_config``. + The schema is defined as an OpenAPI 3.0.2 `Schema + Object `__. + AutoML Models always have this field populated by AI + Platform. Note: The URI given on output will be immutable + and probably different, including the URI scheme, than the + one given on input. The output URI will point to a location + where the user only has a read access. + explanation_metadata (explain.ExplanationMetadata): + Optional. Metadata describing the Model's input and output for explanation. + Both `explanation_metadata` and `explanation_parameters` must be + passed together when used. For more details, see + `Ref docs ` + explanation_parameters (explain.ExplanationParameters): + Optional. Parameters to configure explaining for Model's predictions. + For more details, see `Ref docs ` + project: Optional[str]=None, + Project to upload this model to. Overrides project set in + aiplatform.init. + location: Optional[str]=None, + Location to upload this model to. Overrides location set in + aiplatform.init. + credentials: Optional[auth_credentials.Credentials]=None, + Custom credentials to use to upload this model. Overrides credentials + set in aiplatform.init. + labels (Dict[str, str]): + Optional. The labels with user-defined metadata to + organize your Models. + Label keys and values can be no longer than 64 + characters (Unicode codepoints), can only + contain lowercase letters, numeric characters, + underscores and dashes. International characters + are allowed. + See https://goo.gl/xmQnxf for more information + and examples of labels. + encryption_spec_key_name (Optional[str]): + Optional. The Cloud KMS resource identifier of the customer + managed encryption key used to protect the model. Has the + form: + ``projects/my-project/locations/my-region/keyRings/my-kr/cryptoKeys/my-key``. + The key needs to be in the same region as where the compute + resource is created. + + If set, this Model and all sub-resources of this Model will be secured by this key. + + Overrides encryption_spec_key_name set in aiplatform.init. + staging_bucket (str): + Optional. Bucket to stage local model artifacts. Overrides + staging_bucket set in aiplatform.init. + Returns: + model: Instantiated representation of the uploaded model resource. + Raises: + ValueError: If only `explanation_metadata` or `explanation_parameters` + is specified. + Also if model directory does not contain a supported model file. + """ + container_image_uri = aiplatform.helpers.get_prebuilt_prediction_container_uri( + region=location, + framework="tensorflow", + framework_version=tensorflow_version, + accelerator="gpu" if use_gpu else "cpu", + ) + + return cls.upload( + serving_container_image_uri=container_image_uri, + artifact_uri=saved_model_dir, + display_name=display_name, + description=description, + instance_schema_uri=instance_schema_uri, + parameters_schema_uri=parameters_schema_uri, + prediction_schema_uri=prediction_schema_uri, + explanation_metadata=explanation_metadata, + explanation_parameters=explanation_parameters, + project=project, + location=location, + credentials=credentials, + labels=labels, + encryption_spec_key_name=encryption_spec_key_name, + staging_bucket=staging_bucket, + sync=sync, + ) diff --git a/google/cloud/aiplatform/tensorboard/__init__.py b/google/cloud/aiplatform/tensorboard/__init__.py index 93c48cd46c..f4b1c0b105 100644 --- a/google/cloud/aiplatform/tensorboard/__init__.py +++ b/google/cloud/aiplatform/tensorboard/__init__.py @@ -15,7 +15,7 @@ # limitations under the License. # -from google.cloud.aiplatform.tensorboard.tensorboard import Tensorboard +from google.cloud.aiplatform.tensorboard.tensorboard_resource import Tensorboard __all__ = ("Tensorboard",) diff --git a/google/cloud/aiplatform/tensorboard/plugins/tf_profiler/profile_uploader.py b/google/cloud/aiplatform/tensorboard/plugins/tf_profiler/profile_uploader.py index 41020f870e..59dedd0142 100644 --- a/google/cloud/aiplatform/tensorboard/plugins/tf_profiler/profile_uploader.py +++ b/google/cloud/aiplatform/tensorboard/plugins/tf_profiler/profile_uploader.py @@ -38,20 +38,14 @@ import tensorflow as tf from google.cloud import storage -from google.cloud.aiplatform.compat.services import tensorboard_service_client_v1beta1 -from google.cloud.aiplatform.compat.types import ( - tensorboard_data_v1beta1 as tensorboard_data, -) -from google.cloud.aiplatform.compat.types import ( - tensorboard_service_v1beta1 as tensorboard_service, -) -from google.cloud.aiplatform.compat.types import ( - tensorboard_time_series_v1beta1 as tensorboard_time_series, -) +from google.cloud.aiplatform.compat.services import tensorboard_service_client +from google.cloud.aiplatform.compat.types import tensorboard_data +from google.cloud.aiplatform.compat.types import tensorboard_service +from google.cloud.aiplatform.compat.types import tensorboard_time_series from google.cloud.aiplatform.tensorboard import uploader_utils from google.protobuf import timestamp_pb2 as timestamp -TensorboardServiceClient = tensorboard_service_client_v1beta1.TensorboardServiceClient +TensorboardServiceClient = tensorboard_service_client.TensorboardServiceClient logger = tb_logging.get_logger() diff --git a/google/cloud/aiplatform/tensorboard/tensorboard.py b/google/cloud/aiplatform/tensorboard/tensorboard_resource.py similarity index 97% rename from google/cloud/aiplatform/tensorboard/tensorboard.py rename to google/cloud/aiplatform/tensorboard/tensorboard_resource.py index 3fe6507968..1e41cc9755 100644 --- a/google/cloud/aiplatform/tensorboard/tensorboard.py +++ b/google/cloud/aiplatform/tensorboard/tensorboard_resource.py @@ -18,17 +18,13 @@ from typing import Optional, Sequence, Dict, Tuple from google.auth import credentials as auth_credentials +from google.protobuf import field_mask_pb2 from google.cloud.aiplatform import base -from google.cloud.aiplatform import compat +from google.cloud.aiplatform.compat.types import tensorboard as gca_tensorboard from google.cloud.aiplatform import initializer from google.cloud.aiplatform import utils - -from google.cloud.aiplatform.compat.types import tensorboard_v1beta1 as gca_tensorboard - -from google.protobuf import field_mask_pb2 - _LOGGER = base.Logger(__name__) @@ -156,8 +152,7 @@ def create( ) encryption_spec = initializer.global_config.get_encryption_spec( - encryption_spec_key_name=encryption_spec_key_name, - select_version=compat.V1BETA1, + encryption_spec_key_name=encryption_spec_key_name ) gapic_tensorboard = gca_tensorboard.Tensorboard( @@ -254,7 +249,6 @@ def update( if encryption_spec_key_name: encryption_spec = initializer.global_config.get_encryption_spec( encryption_spec_key_name=encryption_spec_key_name, - select_version=compat.V1BETA1, ) update_mask.append("encryption_spec") diff --git a/google/cloud/aiplatform/tensorboard/uploader.py b/google/cloud/aiplatform/tensorboard/uploader.py index 0df67f1a06..735279b03d 100644 --- a/google/cloud/aiplatform/tensorboard/uploader.py +++ b/google/cloud/aiplatform/tensorboard/uploader.py @@ -56,25 +56,17 @@ from google.api_core import exceptions from google.cloud import storage -from google.cloud.aiplatform.compat.services import tensorboard_service_client_v1beta1 -from google.cloud.aiplatform.compat.types import ( - tensorboard_data_v1beta1 as tensorboard_data, -) -from google.cloud.aiplatform.compat.types import ( - tensorboard_experiment_v1beta1 as tensorboard_experiment, -) -from google.cloud.aiplatform.compat.types import ( - tensorboard_service_v1beta1 as tensorboard_service, -) -from google.cloud.aiplatform.compat.types import ( - tensorboard_time_series_v1beta1 as tensorboard_time_series, -) +from google.cloud.aiplatform.compat.services import tensorboard_service_client +from google.cloud.aiplatform.compat.types import tensorboard_data +from google.cloud.aiplatform.compat.types import tensorboard_experiment +from google.cloud.aiplatform.compat.types import tensorboard_service +from google.cloud.aiplatform.compat.types import tensorboard_time_series from google.cloud.aiplatform.tensorboard import uploader_utils from google.cloud.aiplatform.tensorboard.plugins.tf_profiler import profile_uploader from google.protobuf import message from google.protobuf import timestamp_pb2 as timestamp -TensorboardServiceClient = tensorboard_service_client_v1beta1.TensorboardServiceClient +TensorboardServiceClient = tensorboard_service_client.TensorboardServiceClient # Minimum length of a logdir polling cycle in seconds. Shorter cycles will # sleep to avoid spinning over the logdir, which isn't great for disks and can diff --git a/google/cloud/aiplatform/tensorboard/uploader_main.py b/google/cloud/aiplatform/tensorboard/uploader_main.py index 7c868fcfb7..ba259d6388 100644 --- a/google/cloud/aiplatform/tensorboard/uploader_main.py +++ b/google/cloud/aiplatform/tensorboard/uploader_main.py @@ -28,8 +28,11 @@ from tensorboard.plugins.image import metadata as images_metadata from tensorboard.plugins.graph import metadata as graphs_metadata +from google.api_core import exceptions from google.cloud import storage from google.cloud import aiplatform +from google.cloud.aiplatform.constants import base as constants +from google.cloud.aiplatform import jobs from google.cloud.aiplatform.tensorboard import uploader from google.cloud.aiplatform.utils import TensorboardClientWithOverride @@ -89,7 +92,7 @@ def main(argv): if len(argv) > 1: raise app.UsageError("Too many command-line arguments.") - aiplatform.constants.API_BASE_PATH = FLAGS.api_uri + constants.API_BASE_PATH = FLAGS.api_uri m = re.match( "projects/(.*)/locations/(.*)/tensorboards/.*", FLAGS.tensorboard_resource_name ) @@ -123,9 +126,14 @@ def main(argv): exitcode=0, ) + experiment_name = FLAGS.experiment_name + experiment_display_name = get_experiment_display_name_with_override( + experiment_name, FLAGS.experiment_display_name, project_id, region + ) + tb_uploader = uploader.TensorBoardUploader( - experiment_name=FLAGS.experiment_name, - experiment_display_name=FLAGS.experiment_display_name, + experiment_name=experiment_name, + experiment_display_name=experiment_display_name, tensorboard_resource_name=tensorboard.name, blob_storage_bucket=blob_storage_bucket, blob_storage_folder=blob_storage_folder, @@ -149,6 +157,19 @@ def main(argv): tb_uploader.start_uploading() +def get_experiment_display_name_with_override( + experiment_name, experiment_display_name, project_id, region +): + if experiment_name.isdecimal() and not experiment_display_name: + try: + return jobs.CustomJob.get( + resource_name=experiment_name, project=project_id, location=region, + ).display_name + except exceptions.NotFound: + return experiment_display_name + return experiment_display_name + + def flags_parser(args): # Plumbs the flags defined in this file to the main module, mostly for the # console script wrapper tb-gcp-uploader. diff --git a/google/cloud/aiplatform/tensorboard/uploader_utils.py b/google/cloud/aiplatform/tensorboard/uploader_utils.py index 679eb02ef4..1396f6cc78 100644 --- a/google/cloud/aiplatform/tensorboard/uploader_utils.py +++ b/google/cloud/aiplatform/tensorboard/uploader_utils.py @@ -29,18 +29,12 @@ from google.api_core import exceptions from google.cloud import storage -from google.cloud.aiplatform.compat.types import ( - tensorboard_run_v1beta1 as tensorboard_run, -) -from google.cloud.aiplatform.compat.types import ( - tensorboard_service_v1beta1 as tensorboard_service, -) -from google.cloud.aiplatform.compat.types import ( - tensorboard_time_series_v1beta1 as tensorboard_time_series, -) -from google.cloud.aiplatform.compat.services import tensorboard_service_client_v1beta1 - -TensorboardServiceClient = tensorboard_service_client_v1beta1.TensorboardServiceClient +from google.cloud.aiplatform.compat.types import tensorboard_run +from google.cloud.aiplatform.compat.types import tensorboard_service +from google.cloud.aiplatform.compat.types import tensorboard_time_series +from google.cloud.aiplatform.compat.services import tensorboard_service_client + +TensorboardServiceClient = tensorboard_service_client.TensorboardServiceClient logger = tb_logging.get_logger() logger.setLevel(logging.WARNING) @@ -201,7 +195,7 @@ def _create_or_get_run_resource( Required. The display name of this run. Returns: - tb_run (google.cloud.aiplatform_v1beta1.types.TensorboardRun): + tb_run (tensorboard_run.TensorboardRun): The TensorboardRun given the run_name. Raises: @@ -412,7 +406,6 @@ def get_or_create( filter="display_name = {}".format(json.dumps(str(tag_name))), ) ) - num = 0 time_series = None diff --git a/google/cloud/aiplatform/training_jobs.py b/google/cloud/aiplatform/training_jobs.py index 679bb277ab..4afd4920db 100644 --- a/google/cloud/aiplatform/training_jobs.py +++ b/google/cloud/aiplatform/training_jobs.py @@ -23,7 +23,7 @@ from google.auth import credentials as auth_credentials from google.cloud.aiplatform import base -from google.cloud.aiplatform import constants +from google.cloud.aiplatform.constants import base as constants from google.cloud.aiplatform import datasets from google.cloud.aiplatform import initializer from google.cloud.aiplatform import models diff --git a/google/cloud/aiplatform/training_utils/cloud_profiler/README.rst b/google/cloud/aiplatform/training_utils/cloud_profiler/README.rst new file mode 100644 index 0000000000..6c6cfc1af9 --- /dev/null +++ b/google/cloud/aiplatform/training_utils/cloud_profiler/README.rst @@ -0,0 +1,20 @@ +Cloud Profiler +================================= + +Cloud Profiler allows you to profile your remote Vertex AI Training jobs on demand and visualize the results in Vertex Tensorboard. + +Quick Start +------------ + +To start using the profiler with TensorFlow, update your training script to include the following: + +.. code-block:: Python + + from google.cloud.aiplatform.training_utils import cloud_profiler + ... + cloud_profiler.init() + + +Next, run the job with with a Vertex TensorBoard instance. For full details on how to do this, visit https://cloud.google.com/vertex-ai/docs/experiments/tensorboard-overview + +Finally, visit your TensorBoard in your Google Cloud Console, navigate to the "Profile" tab, and click the `Capture Profile` button. This will allow users to capture profiling statistics for the running jobs. diff --git a/google/cloud/aiplatform/training_utils/cloud_profiler/__init__.py b/google/cloud/aiplatform/training_utils/cloud_profiler/__init__.py new file mode 100644 index 0000000000..1b0c5eb925 --- /dev/null +++ b/google/cloud/aiplatform/training_utils/cloud_profiler/__init__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +# 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 +# +# 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. +# + +from google.cloud.aiplatform.training_utils.cloud_profiler import initializer + +""" +Initialize the cloud profiler for tensorflow. + +Usage: +from google.cloud.aiplatform.training_utils import cloud_profiler + +cloud_profiler.init(profiler='tensorflow') +""" + +init = initializer.initialize diff --git a/google/cloud/aiplatform/training_utils/cloud_profiler/cloud_profiler_utils.py b/google/cloud/aiplatform/training_utils/cloud_profiler/cloud_profiler_utils.py new file mode 100644 index 0000000000..f7f6e8d8f6 --- /dev/null +++ b/google/cloud/aiplatform/training_utils/cloud_profiler/cloud_profiler_utils.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +# 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 +# +# 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. +# + +import_error_msg = ( + "Could not load the cloud profiler. To use the profiler, " + "install the SDK using 'pip install google-cloud-aiplatform[cloud-profiler]'" +) diff --git a/google/cloud/aiplatform/training_utils/cloud_profiler/initializer.py b/google/cloud/aiplatform/training_utils/cloud_profiler/initializer.py new file mode 100644 index 0000000000..5bb5d19391 --- /dev/null +++ b/google/cloud/aiplatform/training_utils/cloud_profiler/initializer.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- + +# 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 +# +# 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. +# + +import logging +import threading +from typing import Optional, Type + +from google.cloud.aiplatform.training_utils.cloud_profiler import cloud_profiler_utils + +try: + from werkzeug import serving +except ImportError as err: + raise ImportError(cloud_profiler_utils.import_error_msg) from err + + +from google.cloud.aiplatform.training_utils import environment_variables +from google.cloud.aiplatform.training_utils.cloud_profiler import webserver +from google.cloud.aiplatform.training_utils.cloud_profiler.plugins import base_plugin +from google.cloud.aiplatform.training_utils.cloud_profiler.plugins.tensorflow import ( + tf_profiler, +) + + +# Mapping of available plugins to use +_AVAILABLE_PLUGINS = {"tensorflow": tf_profiler.TFProfiler} + + +class MissingEnvironmentVariableException(Exception): + pass + + +def _build_plugin( + plugin: Type[base_plugin.BasePlugin], +) -> Optional[base_plugin.BasePlugin]: + """Builds the plugin given the object. + + Args: + plugin (Type[base_plugin]): + Required. An uninitialized plugin class. + + Returns: + An initialized plugin, or None if plugin cannot be + initialized. + """ + if not plugin.can_initialize(): + logging.warning("Cannot initialize the plugin") + return + + plugin.setup() + + if not plugin.post_setup_check(): + return + + return plugin() + + +def _run_app_thread(server: webserver.WebServer, port: int): + """Run the webserver in a separate thread. + + Args: + server (webserver.WebServer): + Required. A webserver to accept requests. + port (int): + Required. The port to run the webserver on. + """ + daemon = threading.Thread( + name="profile_server", + target=serving.run_simple, + args=("0.0.0.0", port, server,), + ) + daemon.setDaemon(True) + daemon.start() + + +def initialize(plugin: str = "tensorflow"): + """Initializes the profiling SDK. + + Args: + plugin (str): + Required. Name of the plugin to initialize. + Current options are ["tensorflow"] + + Raises: + ValueError: + The plugin does not exist. + MissingEnvironmentVariableException: + An environment variable that is needed is not set. + """ + plugin_obj = _AVAILABLE_PLUGINS.get(plugin) + + if not plugin_obj: + raise ValueError( + "Plugin {} not available, must choose from {}".format( + plugin, _AVAILABLE_PLUGINS.keys() + ) + ) + + prof_plugin = _build_plugin(plugin_obj) + + if prof_plugin is None: + return + + server = webserver.WebServer([prof_plugin]) + + if not environment_variables.http_handler_port: + raise MissingEnvironmentVariableException( + "'AIP_HTTP_HANDLER_PORT' must be set." + ) + + port = int(environment_variables.http_handler_port) + + _run_app_thread(server, port) diff --git a/google/cloud/aiplatform/training_utils/cloud_profiler/plugins/base_plugin.py b/google/cloud/aiplatform/training_utils/cloud_profiler/plugins/base_plugin.py new file mode 100644 index 0000000000..67b6b40ae9 --- /dev/null +++ b/google/cloud/aiplatform/training_utils/cloud_profiler/plugins/base_plugin.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +# 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 +# +# 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. +# + +import abc +from typing import Callable, Dict +from werkzeug import Response + + +class BasePlugin(abc.ABC): + """Base plugin for cloud training tools endpoints. + + The plugins support registering http handlers to be used for + AI Platform training jobs. + """ + + @staticmethod + @abc.abstractmethod + def setup() -> None: + """Run any setup code for the plugin before webserver is launched.""" + raise NotImplementedError + + @staticmethod + @abc.abstractmethod + def can_initialize() -> bool: + """Check whether a plugin is able to be initialized. + + Used for checking if correct dependencies are installed, system requirements, etc. + + Returns: + Bool indicating whether the plugin can be initialized. + """ + raise NotImplementedError + + @staticmethod + @abc.abstractmethod + def post_setup_check() -> bool: + """Check if after initialization, we need to use the plugin. + + Example: Web server only needs to run for main node for training, others + just need to have 'setup()' run to start the rpc server. + + Returns: + A boolean indicating whether post setup checks pass. + """ + raise NotImplementedError + + @abc.abstractmethod + def get_routes(self) -> Dict[str, Callable[..., Response]]: + """Get the mapping from path to handler. + + This is the method in which plugins can assign different routes to + different handlers. + + Returns: + A mapping from a route to a handler. + """ + raise NotImplementedError diff --git a/google/cloud/aiplatform/training_utils/cloud_profiler/plugins/tensorflow/tensorboard_api.py b/google/cloud/aiplatform/training_utils/cloud_profiler/plugins/tensorflow/tensorboard_api.py new file mode 100644 index 0000000000..4da8381b4c --- /dev/null +++ b/google/cloud/aiplatform/training_utils/cloud_profiler/plugins/tensorflow/tensorboard_api.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- + +# 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 +# +# 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. +# + +"""Helpers for creating a profile request sender for tf profiler plugin.""" + +import os +import re +from typing import Tuple + +from tensorboard.uploader import upload_tracker +from tensorboard.uploader import util +from tensorboard.uploader.proto import server_info_pb2 +from tensorboard.util import tb_logging + +from google.api_core import exceptions +from google.cloud import aiplatform +from google.cloud import storage +from google.cloud.aiplatform.utils import TensorboardClientWithOverride +from google.cloud.aiplatform.tensorboard import uploader_utils +from google.cloud.aiplatform.compat.types import ( + tensorboard_experiment_v1beta1 as tensorboard_experiment, +) +from google.cloud.aiplatform.tensorboard.plugins.tf_profiler import profile_uploader +from google.cloud.aiplatform import training_utils + +logger = tb_logging.get_logger() + + +def _get_api_client() -> TensorboardClientWithOverride: + """Creates an Tensorboard API client.""" + aiplatform.constants.API_BASE_PATH = ( + training_utils.environment_variables.tensorboard_api_uri + ) + m = re.match( + "projects/.*/locations/(.*)/tensorboards/.*", + training_utils.environment_variables.tensorboard_resource_name, + ) + region = m[1] + + api_client = aiplatform.initializer.global_config.create_client( + client_class=TensorboardClientWithOverride, location_override=region, + ) + + return api_client + + +def _get_project_id() -> str: + """Gets the project id from the tensorboard resource name. + + Returns: + Project ID for current project. + + Raises: + ValueError: Cannot parse the tensorboard resource name. + """ + m = re.match( + "projects/(.*)/locations/.*/tensorboards/.*", + training_utils.environment_variables.tensorboard_resource_name, + ) + if not m: + raise ValueError( + "Incorrect format for tensorboard resource name: %s", + training_utils.environment_variables.tensorboard_resource_name, + ) + return m[1] + + +def _make_upload_limits() -> server_info_pb2.UploadLimits: + """Creates the upload limits for tensorboard. + + Returns: + An UploadLimits object. + """ + upload_limits = server_info_pb2.UploadLimits() + upload_limits.min_blob_request_interval = 10 + upload_limits.max_blob_request_size = 4 * (2 ** 20) - 256 * (2 ** 10) + upload_limits.max_blob_size = 10 * (2 ** 30) # 10GiB + + return upload_limits + + +def _get_blob_items( + api_client: TensorboardClientWithOverride, +) -> Tuple[storage.bucket.Bucket, str]: + """Gets the blob storage items for the tensorboard resource. + + Args: + api_client (): + Required. Client go get information about the tensorboard instance. + + Returns: + A tuple of storage buckets and the blob storage folder name. + """ + project_id = _get_project_id() + tensorboard = api_client.get_tensorboard( + name=training_utils.environment_variables.tensorboard_resource_name + ) + + path_prefix = tensorboard.blob_storage_path_prefix + "/" + first_slash_index = path_prefix.find("/") + bucket_name = path_prefix[:first_slash_index] + blob_storage_bucket = storage.Client(project=project_id).bucket(bucket_name) + blob_storage_folder = path_prefix[first_slash_index + 1 :] + + return blob_storage_bucket, blob_storage_folder + + +def _get_or_create_experiment( + api: TensorboardClientWithOverride, experiment_name: str +) -> str: + """Creates a tensorboard experiment. + + Args: + api (TensorboardClientWithOverride): + Required. An api for interfacing with tensorboard resources. + experiment_name (str): + Required. The name of the experiment to get or create. + + Returns: + The name of the experiment. + """ + tb_experiment = tensorboard_experiment.TensorboardExperiment() + + try: + experiment = api.create_tensorboard_experiment( + parent=training_utils.environment_variables.tensorboard_resource_name, + tensorboard_experiment=tb_experiment, + tensorboard_experiment_id=experiment_name, + ) + except exceptions.AlreadyExists: + logger.info("Creating experiment failed. Retrieving experiment.") + experiment_name = os.path.join( + training_utils.environment_variables.tensorboard_resource_name, + "experiments", + experiment_name, + ) + experiment = api.get_tensorboard_experiment(name=experiment_name) + + return experiment.name + + +def create_profile_request_sender() -> profile_uploader.ProfileRequestSender: + """Creates the `ProfileRequestSender` for the profile plugin. + + A profile request sender is created for the plugin so that after profiling runs + have finished, data can be uploaded to the tensorboard backend. + + Returns: + A ProfileRequestSender object. + """ + api_client = _get_api_client() + + experiment_name = _get_or_create_experiment( + api_client, training_utils.environment_variables.cloud_ml_job_id + ) + + upload_limits = _make_upload_limits() + + blob_rpc_rate_limiter = util.RateLimiter( + upload_limits.min_blob_request_interval / 100 + ) + + blob_storage_bucket, blob_storage_folder = _get_blob_items(api_client,) + + source_bucket = uploader_utils.get_source_bucket( + training_utils.environment_variables.tensorboard_log_dir + ) + + profile_request_sender = profile_uploader.ProfileRequestSender( + experiment_name, + api_client, + upload_limits=upload_limits, + blob_rpc_rate_limiter=blob_rpc_rate_limiter, + blob_storage_bucket=blob_storage_bucket, + blob_storage_folder=blob_storage_folder, + source_bucket=source_bucket, + tracker=upload_tracker.UploadTracker(verbosity=1), + logdir=training_utils.environment_variables.tensorboard_log_dir, + ) + + return profile_request_sender diff --git a/google/cloud/aiplatform/training_utils/cloud_profiler/plugins/tensorflow/tf_profiler.py b/google/cloud/aiplatform/training_utils/cloud_profiler/plugins/tensorflow/tf_profiler.py new file mode 100644 index 0000000000..1f0bbccc3b --- /dev/null +++ b/google/cloud/aiplatform/training_utils/cloud_profiler/plugins/tensorflow/tf_profiler.py @@ -0,0 +1,350 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""A plugin to handle remote tensoflow profiler sessions for Vertex AI.""" + +from google.cloud.aiplatform.training_utils.cloud_profiler import cloud_profiler_utils + +try: + import tensorflow as tf + from tensorboard_plugin_profile.profile_plugin import ProfilePlugin +except ImportError as err: + raise ImportError(cloud_profiler_utils.import_error_msg) from err + +import argparse +from collections import namedtuple +import importlib.util +import json +import logging +from typing import Callable, Dict, Optional +from urllib import parse + +import tensorboard.plugins.base_plugin as tensorboard_base_plugin +from werkzeug import Response + +from google.cloud.aiplatform.tensorboard.plugins.tf_profiler import profile_uploader +from google.cloud.aiplatform.training_utils import environment_variables +from google.cloud.aiplatform.training_utils.cloud_profiler import wsgi_types +from google.cloud.aiplatform.training_utils.cloud_profiler.plugins import base_plugin +from google.cloud.aiplatform.training_utils.cloud_profiler.plugins.tensorflow import ( + tensorboard_api, +) + + +# TF verison information. +Version = namedtuple("Version", ["major", "minor", "patch"]) + +logger = logging.Logger("tf-profiler") + +_BASE_TB_ENV_WARNING = ( + "To set this environment variable, run your training with the 'tensorboard' " + "option. For more information on how to run with training with tensorboard, visit " + "https://cloud.google.com/vertex-ai/docs/experiments/tensorboard-training" +) + + +def _get_tf_versioning() -> Optional[Version]: + """Convert version string to a Version namedtuple for ease of parsing. + + Returns: + A version object if finding the version was successful, None otherwise. + """ + version = tf.__version__ + + versioning = version.split(".") + if len(versioning) != 3: + return + + return Version(int(versioning[0]), int(versioning[1]), int(versioning[2])) + + +def _is_compatible_version(version: Version) -> bool: + """Check if version is compatible with tf profiling. + + Profiling plugin is available to be used for version >= 2.4.0. + While the profiler is available in 2.2.0 >=, some additional dependencies + that are included in 2.4.0 >= are also needed for the tensorboard-plugin-profile. + + Profiler: + https://www.tensorflow.org/guide/profiler + Required commit for tensorboard-plugin-profile: + https://github.com/tensorflow/tensorflow/commit/8b9c207242db515daef033e74d69ea5d8e023dc6 + + Args: + version (Version): + Required. `Verison` of tensorflow. + + Returns: + Bool indicating wheter version is compatible with profiler. + """ + return version.major >= 2 and version.minor >= 4 + + +def _check_tf() -> bool: + """Check whether all the tensorflow prereqs are met. + + Returns: + True if all requirements met, False otherwise. + """ + # Check tf is installed + if importlib.util.find_spec("tensorflow") is None: + logger.warning("Tensorflow not installed, cannot initialize profiling plugin") + return False + + # Check tensorflow version + version = _get_tf_versioning() + if version is None: + logger.warning( + "Could not find major, minor, and patch versions of tensorflow. Version found: %s", + version, + ) + return False + + # Check compatibility, introduced in tensorflow >= 2.2.0 + if not _is_compatible_version(version): + logger.warning( + "Version %s is incompatible with tf profiler." + "To use the profiler, choose a version >= 2.2.0", + "%s.%s.%s" % (version.major, version.minor, version.patch), + ) + return False + + # Check for the tf profiler plugin + if importlib.util.find_spec("tensorboard_plugin_profile") is None: + logger.warning( + "Could not import tensorboard_plugin_profile, will not run tf profiling service" + ) + return False + + return True + + +def _create_profiling_context() -> tensorboard_base_plugin.TBContext: + """Creates the base context needed for TB Profiler. + + Returns: + An initialized `TBContext`. + """ + + context_flags = argparse.Namespace(master_tpu_unsecure_channel=None) + + context = tensorboard_base_plugin.TBContext( + logdir=environment_variables.tensorboard_log_dir, + multiplexer=None, + flags=context_flags, + ) + + return context + + +def _host_to_grpc(hostname: str) -> str: + """Format a hostname to a grpc address. + + Args: + hostname (str): + Required. Address in form: `{hostname}:{port}` + + Returns: + Address in form of: 'grpc://{hostname}:{port}' + """ + return ( + "grpc://" + + "".join(hostname.split(":")[:-1]) + + ":" + + environment_variables.tf_profiler_port + ) + + +def _get_hostnames() -> Optional[str]: + """Get the hostnames for all servers running. + + Returns: + A host formatted by `_host_to_grpc` if obtaining the cluster spec + is successful, None otherwise. + """ + cluster_spec = environment_variables.cluster_spec + if cluster_spec is None: + return + + cluster = cluster_spec.get("cluster", "") + if not cluster: + return + + hostnames = [] + for value in cluster.values(): + hostnames.extend(value) + + return ",".join([_host_to_grpc(x) for x in hostnames]) + + +def _update_environ(environ: wsgi_types.Environment) -> bool: + """Add parameters to the query that are retrieved from training side. + + Args: + environ (wsgi_types.Environment): + Required. The WSGI Environment. + + Returns: + Whether the environment was successfully updated. + """ + hosts = _get_hostnames() + + if hosts is None: + return False + + query_dict = {} + query_dict["service_addr"] = hosts + + # Update service address and worker list + # Use parse_qsl and then convert list to dictionary so we can update + # attributes + prev_query_string = dict(parse.parse_qsl(environ["QUERY_STRING"])) + prev_query_string.update(query_dict) + + environ["QUERY_STRING"] = parse.urlencode(prev_query_string) + + return True + + +def warn_tensorboard_env_var(var_name: str): + """Warns if a tensorboard related environment variable is missing. + + Args: + var_name (str): + Required. The name of the missing environment variable. + """ + logging.warning( + f"Environment variable `{var_name}` must be set. " + _BASE_TB_ENV_WARNING + ) + + +def _check_env_vars() -> bool: + """Determine whether the correct environment variables are set. + + Returns: + bool indicating all necessary variables are set. + """ + # The below are tensorboard specific environment variables. + if environment_variables.tf_profiler_port is None: + warn_tensorboard_env_var("AIP_TF_PROFILER_PORT") + return False + + if environment_variables.tensorboard_log_dir is None: + warn_tensorboard_env_var("AIP_TENSORBOARD_LOG_DIR") + return False + + if environment_variables.tensorboard_api_uri is None: + warn_tensorboard_env_var("AIP_TENSORBOARD_API_URI") + return False + + if environment_variables.tensorboard_resource_name is None: + warn_tensorboard_env_var("AIP_TENSORBOARD_RESOURCE_NAME") + return False + + # These environment variables are not tensorboard related, they are + # variables set for any Vertex training run. + cluster_spec = environment_variables.cluster_spec + if cluster_spec is None: + logger.warning("Environment variable `CLUSTER_SPEC` is not set.") + return False + + if environment_variables.cloud_ml_job_id is None: + logger.warning("Environment variable `CLOUD_ML_JOB_ID` is not set") + return False + + return True + + +class TFProfiler(base_plugin.BasePlugin): + """Handler for Tensorflow Profiling.""" + + PLUGIN_NAME = "profile" + + def __init__(self): + """Build a TFProfiler object.""" + context = _create_profiling_context() + self._profile_request_sender: profile_uploader.ProfileRequestSender = tensorboard_api.create_profile_request_sender() + self._profile_plugin: ProfilePlugin = ProfilePlugin(context) + + def get_routes( + self, + ) -> Dict[str, Callable[[Dict[str, str], Callable[..., None]], Response]]: + """List of routes to serve. + + Returns: + A callable that takes an werkzeug env and start response and returns a response. + """ + return {"/capture_profile": self.capture_profile_wrapper} + + # Define routes below + def capture_profile_wrapper( + self, environ: wsgi_types.Environment, start_response: wsgi_types.StartResponse + ) -> Response: + """Take a request from tensorboard.gcp and run the profiling for the available servers. + + Args: + environ (wsgi_types.Environment): + Required. The WSGI environment. + start_response (wsgi_types.StartResponse): + Required. The response callable provided by the WSGI server. + + Returns: + A response iterable. + """ + # The service address (localhost) and worker list are populated locally + if not _update_environ(environ): + err = {"error": "Could not parse the environ: %s"} + return Response( + json.dumps(err), content_type="application/json", status=500 + ) + + response = self._profile_plugin.capture_route(environ, start_response) + + self._profile_request_sender.send_request("") + + return response + + # End routes + + @staticmethod + def setup() -> None: + """Sets up the plugin.""" + tf.profiler.experimental.server.start( + int(environment_variables.tf_profiler_port) + ) + + @staticmethod + def post_setup_check() -> bool: + """Only chief and task 0 should run the webserver.""" + cluster_spec = environment_variables.cluster_spec + task_type = cluster_spec.get("task", {}).get("type", "") + task_index = cluster_spec.get("task", {}).get("index", -1) + + return task_type in {"workerpool0", "chief"} and task_index == 0 + + @staticmethod + def can_initialize() -> bool: + """Check that we can use the TF Profiler plugin. + + This function checks a number of dependencies for the plugin to ensure we have the + right packages installed, the necessary versions, and the correct environment variables set. + + Returns: + True if can initialize, False otherwise. + """ + + return _check_env_vars() and _check_tf() diff --git a/google/cloud/aiplatform/training_utils/cloud_profiler/webserver.py b/google/cloud/aiplatform/training_utils/cloud_profiler/webserver.py new file mode 100644 index 0000000000..3f7706bb34 --- /dev/null +++ b/google/cloud/aiplatform/training_utils/cloud_profiler/webserver.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- + +# 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 +# +# 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. +# + +"""A basic webserver for hosting plugin routes.""" + +import os + +from google.cloud.aiplatform.training_utils.cloud_profiler import wsgi_types +from google.cloud.aiplatform.training_utils.cloud_profiler.plugins import base_plugin +from typing import List +from werkzeug import wrappers, Response + + +class WebServer: + """A basic web server for handling requests.""" + + def __init__(self, plugins: List[base_plugin.BasePlugin]): + """Creates a web server to host plugin routes. + + Args: + plugins (List[base_plugin.BasePlugin]): + Required. A list of `BasePlugin` objects. + + Raises: + ValueError: + When there is an invalid route passed from + one of the plugins. + """ + + self._plugins = plugins + self._routes = {} + + # Routes are in form {plugin_name}/{route} + for plugin in self._plugins: + for route, handler in plugin.get_routes().items(): + if not route.startswith("/"): + raise ValueError( + 'Routes should start with a "/", ' + "invalid route for plugin %s, route %s" + % (plugin.PLUGIN_NAME, route) + ) + + app_route = os.path.join("/", plugin.PLUGIN_NAME) + + app_route += route + self._routes[app_route] = handler + + def dispatch_request( + self, environ: wsgi_types.Environment, start_response: wsgi_types.StartResponse + ) -> Response: + """Handles the routing of requests. + + Args: + environ (wsgi_types.Environment): + Required. The WSGI environment. + start_response (wsgi_types.StartResponse): + Required. The response callable provided by the WSGI server. + + Returns: + A response iterable. + """ + # Check for existince of route + request = wrappers.Request(environ) + + if request.path in self._routes: + return self._routes[request.path](environ, start_response) + + response = wrappers.Response("Not Found", status=404) + return response(environ, start_response) + + def wsgi_app( + self, environ: wsgi_types.Environment, start_response: wsgi_types.StartResponse + ) -> Response: + """Entrypoint for wsgi application. + + Args: + environ (wsgi_types.Environment): + Required. The WSGI environment. + start_response (wsgi_types.StartResponse): + Required. The response callable provided by the WSGI server. + + Returns: + A response iterable. + """ + response = self.dispatch_request(environ, start_response) + return response + + def __call__(self, environ, start_response): + """Entrypoint for wsgi application. + + Args: + environ (wsgi_types.Environment): + Required. The WSGI environment. + start_response (wsgi_types.StartResponse): + Required. The response callable provided by the WSGI server. + + Returns: + A response iterable. + """ + return self.wsgi_app(environ, start_response) diff --git a/google/cloud/aiplatform/training_utils/cloud_profiler/wsgi_types.py b/google/cloud/aiplatform/training_utils/cloud_profiler/wsgi_types.py new file mode 100644 index 0000000000..0348c5b91e --- /dev/null +++ b/google/cloud/aiplatform/training_utils/cloud_profiler/wsgi_types.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +# 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 +# +# 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. +# + +# Typing description for the WSGI App callables +# For more information on WSGI, see PEP 3333 + +from typing import Any, Dict, Text, Callable + +# Contain CGI environment variables, as defined by the Common Gateway Interface +# specification. +Environment = Dict[Text, Any] + +# Used to begin the HTTP response. +StartResponse = Callable[..., Callable[[bytes], None]] diff --git a/google/cloud/aiplatform/training_utils/environment_variables.py b/google/cloud/aiplatform/training_utils/environment_variables.py index 2771c0746c..0783e78251 100644 --- a/google/cloud/aiplatform/training_utils/environment_variables.py +++ b/google/cloud/aiplatform/training_utils/environment_variables.py @@ -15,6 +15,8 @@ # limitations under the License. # +# Environment variables used in Vertex AI Training. + import json import os @@ -74,3 +76,6 @@ def _json_helper(env_var: str) -> Optional[Dict]: # The name given to the training job. cloud_ml_job_id = os.environ.get("CLOUD_ML_JOB_ID") + +# The HTTP Handler port to use to host the profiling webserver. +http_handler_port = os.environ.get("AIP_HTTP_HANDLER_PORT") diff --git a/google/cloud/aiplatform/utils/__init__.py b/google/cloud/aiplatform/utils/__init__.py index 56baa42a9d..cac1248ee7 100644 --- a/google/cloud/aiplatform/utils/__init__.py +++ b/google/cloud/aiplatform/utils/__init__.py @@ -30,12 +30,14 @@ from google.cloud import storage from google.cloud.aiplatform import compat -from google.cloud.aiplatform import constants +from google.cloud.aiplatform.constants import base as constants from google.cloud.aiplatform import initializer from google.cloud.aiplatform.compat.services import ( dataset_service_client_v1beta1, endpoint_service_client_v1beta1, + featurestore_online_serving_service_client_v1beta1, + featurestore_service_client_v1beta1, job_service_client_v1beta1, metadata_service_client_v1beta1, model_service_client_v1beta1, @@ -46,11 +48,14 @@ from google.cloud.aiplatform.compat.services import ( dataset_service_client_v1, endpoint_service_client_v1, + featurestore_online_serving_service_client_v1, + featurestore_service_client_v1, job_service_client_v1, metadata_service_client_v1, model_service_client_v1, pipeline_service_client_v1, prediction_service_client_v1, + tensorboard_service_client_v1, ) from google.cloud.aiplatform.compat.types import ( @@ -62,19 +67,25 @@ # v1beta1 dataset_service_client_v1beta1.DatasetServiceClient, endpoint_service_client_v1beta1.EndpointServiceClient, + featurestore_online_serving_service_client_v1beta1.FeaturestoreOnlineServingServiceClient, + featurestore_service_client_v1beta1.FeaturestoreServiceClient, model_service_client_v1beta1.ModelServiceClient, prediction_service_client_v1beta1.PredictionServiceClient, pipeline_service_client_v1beta1.PipelineServiceClient, job_service_client_v1beta1.JobServiceClient, metadata_service_client_v1beta1.MetadataServiceClient, + tensorboard_service_client_v1beta1.TensorboardServiceClient, # v1 dataset_service_client_v1.DatasetServiceClient, endpoint_service_client_v1.EndpointServiceClient, + featurestore_online_serving_service_client_v1.FeaturestoreOnlineServingServiceClient, + featurestore_service_client_v1.FeaturestoreServiceClient, metadata_service_client_v1.MetadataServiceClient, model_service_client_v1.ModelServiceClient, prediction_service_client_v1.PredictionServiceClient, pipeline_service_client_v1.PipelineServiceClient, job_service_client_v1.JobServiceClient, + tensorboard_service_client_v1.TensorboardServiceClient, ) RESOURCE_NAME_PATTERN = re.compile( @@ -450,6 +461,30 @@ class EndpointClientWithOverride(ClientWithOverride): ) +class FeaturestoreClientWithOverride(ClientWithOverride): + _is_temporary = True + _default_version = compat.DEFAULT_VERSION + _version_map = ( + (compat.V1, featurestore_service_client_v1.FeaturestoreServiceClient), + (compat.V1BETA1, featurestore_service_client_v1beta1.FeaturestoreServiceClient), + ) + + +class FeaturestoreOnlineServingClientWithOverride(ClientWithOverride): + _is_temporary = False + _default_version = compat.DEFAULT_VERSION + _version_map = ( + ( + compat.V1, + featurestore_online_serving_service_client_v1.FeaturestoreOnlineServingServiceClient, + ), + ( + compat.V1BETA1, + featurestore_online_serving_service_client_v1beta1.FeaturestoreOnlineServingServiceClient, + ), + ) + + class JobClientWithOverride(ClientWithOverride): _is_temporary = True _default_version = compat.DEFAULT_VERSION @@ -506,8 +541,9 @@ class MetadataClientWithOverride(ClientWithOverride): class TensorboardClientWithOverride(ClientWithOverride): _is_temporary = False - _default_version = compat.V1BETA1 + _default_version = compat.DEFAULT_VERSION _version_map = ( + (compat.V1, tensorboard_service_client_v1.TensorboardServiceClient), (compat.V1BETA1, tensorboard_service_client_v1beta1.TensorboardServiceClient), ) @@ -516,6 +552,7 @@ class TensorboardClientWithOverride(ClientWithOverride): "VertexAiServiceClientWithOverride", DatasetClientWithOverride, EndpointClientWithOverride, + FeaturestoreClientWithOverride, JobClientWithOverride, ModelClientWithOverride, PipelineClientWithOverride, diff --git a/google/cloud/aiplatform/utils/enhanced_library/__init__.py b/google/cloud/aiplatform/utils/enhanced_library/__init__.py new file mode 100644 index 0000000000..7e1ec16ec8 --- /dev/null +++ b/google/cloud/aiplatform/utils/enhanced_library/__init__.py @@ -0,0 +1,13 @@ +# 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. diff --git a/google/cloud/aiplatform/helpers/_decorators.py b/google/cloud/aiplatform/utils/enhanced_library/_decorators.py similarity index 97% rename from google/cloud/aiplatform/helpers/_decorators.py rename to google/cloud/aiplatform/utils/enhanced_library/_decorators.py index 95aac31c4f..43e395393b 100644 --- a/google/cloud/aiplatform/helpers/_decorators.py +++ b/google/cloud/aiplatform/utils/enhanced_library/_decorators.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from __future__ import absolute_import -from google.cloud.aiplatform.helpers import value_converter +from google.cloud.aiplatform.utils.enhanced_library import value_converter from proto.marshal import Marshal from proto.marshal.rules.struct import ValueRule diff --git a/google/cloud/aiplatform/helpers/value_converter.py b/google/cloud/aiplatform/utils/enhanced_library/value_converter.py similarity index 100% rename from google/cloud/aiplatform/helpers/value_converter.py rename to google/cloud/aiplatform/utils/enhanced_library/value_converter.py diff --git a/google/cloud/aiplatform/utils/featurestore_utils.py b/google/cloud/aiplatform/utils/featurestore_utils.py new file mode 100644 index 0000000000..c78a96d185 --- /dev/null +++ b/google/cloud/aiplatform/utils/featurestore_utils.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +import re +from typing import Optional, Tuple + +from google.cloud.aiplatform.compat.services import featurestore_service_client + +CompatFeaturestoreServiceClient = featurestore_service_client.FeaturestoreServiceClient + +RESOURCE_ID_PATTERN_REGEX = r"[a-z_][a-z0-9_]{0,59}" + + +def validate_id(resource_id: str) -> bool: + """Validates feature store resource ID pattern.""" + return bool(re.compile(r"^" + RESOURCE_ID_PATTERN_REGEX + r"$").match(resource_id)) + + +def validate_and_get_entity_type_resource_ids( + entity_type_name: str, featurestore_id: Optional[str] = None, +) -> Tuple[str, str]: + """Validates and gets featurestore ID and entity_type ID of the entity_type resource. + + Args: + entity_type_name (str): + Required. A fully-qualified entityType resource name or an entity_type ID + Example: "projects/123/locations/us-central1/featurestores/my_featurestore_id/entityTypes/my_entity_type_id" + or "my_entity_type_id", with featurestore_id passed. + featurestore_id (str): + Optional. Featurestore ID of the entity_type resource. + + Returns: + Tuple[str, str] - featurestore ID and entity_type ID + + Raises: + ValueError if the provided entity_type_name is not in form of a fully-qualified + entityType resource name nor an entity_type ID with featurestore_id passed. + """ + match = CompatFeaturestoreServiceClient.parse_entity_type_path( + path=entity_type_name + ) + + if match: + featurestore_id = match["featurestore"] + entity_type_id = match["entity_type"] + elif ( + validate_id(entity_type_name) + and featurestore_id + and validate_id(featurestore_id) + ): + entity_type_id = entity_type_name + else: + raise ValueError( + f"{entity_type_name} is not in form of a fully-qualified entityType resource name " + f"nor an entity_type ID with featurestore_id passed." + ) + return (featurestore_id, entity_type_id) + + +def validate_and_get_feature_resource_ids( + feature_name: str, + featurestore_id: Optional[str] = None, + entity_type_id: Optional[str] = None, +) -> Tuple[str, str, str]: + """Validates and gets featurestore ID, entity_type ID, and feature ID for the feature resource. + Args: + feature_name (str): + Required. A fully-qualified feature resource name or a feature ID. + Example: "projects/123/locations/us-central1/featurestores/my_featurestore_id/entityTypes/my_entity_type_id/features/my_feature_id" + or "my_feature_id" when project and location are initialized or passed, with featurestore_id and entity_type_id passed. + featurestore_id (str): + Optional. Featurestore ID of the feature resource. + entity_type_id (str): + Optional. EntityType ID of the feature resource. + + Returns: + Tuple[str, str, str] - featurestore ID, entity_type ID, and feature ID + + Raises: + ValueError if the provided feature_name is not in form of a fully-qualified + feature resource name nor a feature ID with featurestore_id and entity_type_id passed. + """ + + match = CompatFeaturestoreServiceClient.parse_feature_path(path=feature_name) + + if match: + featurestore_id = match["featurestore"] + entity_type_id = match["entity_type"] + feature_id = match["feature"] + elif ( + validate_id(feature_name) + and featurestore_id + and entity_type_id + and validate_id(featurestore_id) + and validate_id(entity_type_id) + ): + feature_id = feature_name + else: + raise ValueError( + f"{feature_name} is not in form of a fully-qualified feature resource name " + f"nor a feature ID with featurestore_id and entity_type_id passed." + ) + return (featurestore_id, entity_type_id, feature_id) diff --git a/google/cloud/aiplatform/utils/gcs_utils.py b/google/cloud/aiplatform/utils/gcs_utils.py new file mode 100644 index 0000000000..b7fc2d9291 --- /dev/null +++ b/google/cloud/aiplatform/utils/gcs_utils.py @@ -0,0 +1,163 @@ +# -*- coding: utf-8 -*- + +# 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. + + +import datetime +import glob +import logging +import pathlib +from typing import Optional + +from google.auth import credentials as auth_credentials +from google.cloud import storage + +from google.cloud.aiplatform import initializer + + +_logger = logging.getLogger(__name__) + + +def upload_to_gcs( + source_path: str, + destination_uri: str, + project: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, +): + """Uploads local files to GCS. + + After upload the `destination_uri` will contain the same data as the `source_path`. + + Args: + source_path: Required. Path of the local data to copy to GCS. + destination_uri: Required. GCS URI where the data should be uploaded. + project: Optional. Google Cloud Project that contains the staging bucket. + credentials: The custom credentials to use when making API calls. + If not provided, default credentials will be used. + + Raises: + RuntimeError: When source_path does not exist. + GoogleCloudError: When the upload process fails. + """ + source_path_obj = pathlib.Path(source_path) + if not source_path_obj.exists(): + raise RuntimeError(f"Source path does not exist: {source_path}") + + project = project or initializer.global_config.project + credentials = credentials or initializer.global_config.credentials + + storage_client = storage.Client(project=project, credentials=credentials) + if source_path_obj.is_dir(): + source_file_paths = glob.glob( + pathname=str(source_path_obj / "**"), recursive=True + ) + for source_file_path in source_file_paths: + source_file_path_obj = pathlib.Path(source_file_path) + if source_file_path_obj.is_dir(): + continue + source_file_relative_path_obj = source_file_path_obj.relative_to( + source_path_obj + ) + source_file_relative_posix_path = source_file_relative_path_obj.as_posix() + destination_file_uri = ( + destination_uri.rstrip("/") + "/" + source_file_relative_posix_path + ) + _logger.debug(f'Uploading "{source_file_path}" to "{destination_file_uri}"') + destination_blob = storage.Blob.from_string( + destination_file_uri, client=storage_client + ) + destination_blob.upload_from_filename(filename=source_file_path) + else: + source_file_path = source_path + destination_file_uri = destination_uri + _logger.debug(f'Uploading "{source_file_path}" to "{destination_file_uri}"') + destination_blob = storage.Blob.from_string( + destination_file_uri, client=storage_client + ) + destination_blob.upload_from_filename(filename=source_file_path) + + +def stage_local_data_in_gcs( + data_path: str, + staging_gcs_dir: Optional[str] = None, + project: Optional[str] = None, + location: Optional[str] = None, + credentials: Optional[auth_credentials.Credentials] = None, +) -> str: + """Stages a local data in GCS. + + The file copied to GCS is the name of the local file prepended with an + "aiplatform-{timestamp}-" string. + + Args: + data_path: Required. Path of the local data to copy to GCS. + staging_gcs_dir: + Optional. Google Cloud Storage bucket to be used for data staging. + project: Optional. Google Cloud Project that contains the staging bucket. + location: Optional. Google Cloud location to use for the staging bucket. + credentials: The custom credentials to use when making API calls. + If not provided, default credentials will be used. + + Returns: + Google Cloud Storage URI of the staged data. + + Raises: + RuntimeError: When source_path does not exist. + GoogleCloudError: When the upload process fails. + """ + data_path_obj = pathlib.Path(data_path) + + if not data_path_obj.exists(): + raise RuntimeError(f"Local data does not exist: data_path='{data_path}'") + + staging_gcs_dir = staging_gcs_dir or initializer.global_config.staging_bucket + if not staging_gcs_dir: + project = project or initializer.global_config.project + location = location or initializer.global_config.location + credentials = credentials or initializer.global_config.credentials + # Creating the bucket if it does not exist. + # Currently we only do this when staging_gcs_dir is not specified. + # The buckets that we create are regional. + # This prevents errors when some service required regional bucket. + # E.g. "FailedPrecondition: 400 The Cloud Storage bucket of `gs://...` is in location `us`. It must be in the same regional location as the service location `us-central1`." + # We are making the bucket name region-specific since the bucket is regional. + staging_bucket_name = project + "-vertex-staging-" + location + client = storage.Client(project=project, credentials=credentials) + staging_bucket = storage.Bucket(client=client, name=staging_bucket_name) + if not staging_bucket.exists(): + _logger.info(f'Creating staging GCS bucket "{staging_bucket_name}"') + staging_bucket = client.create_bucket( + bucket_or_name=staging_bucket, project=project, location=location, + ) + staging_gcs_dir = "gs://" + staging_bucket_name + + timestamp = datetime.datetime.now().isoformat(sep="-", timespec="milliseconds") + staging_gcs_subdir = ( + staging_gcs_dir.rstrip("/") + "/vertex_ai_auto_staging/" + timestamp + ) + + staged_data_uri = staging_gcs_subdir + if data_path_obj.is_file(): + staged_data_uri = staging_gcs_subdir + "/" + data_path_obj.name + + _logger.info(f'Uploading "{data_path}" to "{staged_data_uri}"') + upload_to_gcs( + source_path=data_path, + destination_uri=staged_data_uri, + project=project, + credentials=credentials, + ) + + return staged_data_uri diff --git a/google/cloud/aiplatform/v1/schema/trainingjob/definition_v1/types/automl_tables.py b/google/cloud/aiplatform/v1/schema/trainingjob/definition_v1/types/automl_tables.py index 31917ab6e9..0e42e77a86 100644 --- a/google/cloud/aiplatform/v1/schema/trainingjob/definition_v1/types/automl_tables.py +++ b/google/cloud/aiplatform/v1/schema/trainingjob/definition_v1/types/automl_tables.py @@ -55,11 +55,13 @@ class AutoMlTablesInputs(proto.Message): Required when optimization_objective is "maximize-precision-at-recall". Must be between 0 and 1, inclusive. + This field is a member of `oneof`_ ``additional_optimization_objective_config``. optimization_objective_precision_value (float): Required when optimization_objective is "maximize-recall-at-precision". Must be between 0 and 1, inclusive. + This field is a member of `oneof`_ ``additional_optimization_objective_config``. prediction_type (str): The type of prediction the Model is to diff --git a/google/cloud/aiplatform/v1beta1/schema/trainingjob/definition_v1beta1/types/automl_tables.py b/google/cloud/aiplatform/v1beta1/schema/trainingjob/definition_v1beta1/types/automl_tables.py index 9c3b617c23..aae2ec9348 100644 --- a/google/cloud/aiplatform/v1beta1/schema/trainingjob/definition_v1beta1/types/automl_tables.py +++ b/google/cloud/aiplatform/v1beta1/schema/trainingjob/definition_v1beta1/types/automl_tables.py @@ -55,11 +55,13 @@ class AutoMlTablesInputs(proto.Message): Required when optimization_objective is "maximize-precision-at-recall". Must be between 0 and 1, inclusive. + This field is a member of `oneof`_ ``additional_optimization_objective_config``. optimization_objective_precision_value (float): Required when optimization_objective is "maximize-recall-at-precision". Must be between 0 and 1, inclusive. + This field is a member of `oneof`_ ``additional_optimization_objective_config``. prediction_type (str): The type of prediction the Model is to diff --git a/google/cloud/aiplatform/version.py b/google/cloud/aiplatform/version.py index 5c5f4e20aa..9a9bd8f7c3 100644 --- a/google/cloud/aiplatform/version.py +++ b/google/cloud/aiplatform/version.py @@ -15,4 +15,4 @@ # limitations under the License. # -__version__ = "1.7.1" +__version__ = "1.8.0" diff --git a/google/cloud/aiplatform_v1/__init__.py b/google/cloud/aiplatform_v1/__init__.py index b7a4344c4d..6ac922497a 100644 --- a/google/cloud/aiplatform_v1/__init__.py +++ b/google/cloud/aiplatform_v1/__init__.py @@ -44,6 +44,8 @@ from .services.prediction_service import PredictionServiceAsyncClient from .services.specialist_pool_service import SpecialistPoolServiceClient from .services.specialist_pool_service import SpecialistPoolServiceAsyncClient +from .services.tensorboard_service import TensorboardServiceClient +from .services.tensorboard_service import TensorboardServiceAsyncClient from .services.vizier_service import VizierServiceClient from .services.vizier_service import VizierServiceAsyncClient @@ -110,6 +112,7 @@ from .types.event import Event from .types.execution import Execution from .types.explanation import Attribution +from .types.explanation import BlurBaselineConfig from .types.explanation import Explanation from .types.explanation import ExplanationMetadataOverride from .types.explanation import ExplanationParameters @@ -185,6 +188,9 @@ from .types.index_endpoint_service import GetIndexEndpointRequest from .types.index_endpoint_service import ListIndexEndpointsRequest from .types.index_endpoint_service import ListIndexEndpointsResponse +from .types.index_endpoint_service import MutateDeployedIndexOperationMetadata +from .types.index_endpoint_service import MutateDeployedIndexRequest +from .types.index_endpoint_service import MutateDeployedIndexResponse from .types.index_endpoint_service import UndeployIndexOperationMetadata from .types.index_endpoint_service import UndeployIndexRequest from .types.index_endpoint_service import UndeployIndexResponse @@ -387,16 +393,70 @@ from .types.study import Study from .types.study import StudySpec from .types.study import Trial +from .types.tensorboard import Tensorboard +from .types.tensorboard_data import Scalar +from .types.tensorboard_data import TensorboardBlob +from .types.tensorboard_data import TensorboardBlobSequence +from .types.tensorboard_data import TensorboardTensor +from .types.tensorboard_data import TimeSeriesData +from .types.tensorboard_data import TimeSeriesDataPoint +from .types.tensorboard_experiment import TensorboardExperiment +from .types.tensorboard_run import TensorboardRun +from .types.tensorboard_service import BatchCreateTensorboardRunsRequest +from .types.tensorboard_service import BatchCreateTensorboardRunsResponse +from .types.tensorboard_service import BatchCreateTensorboardTimeSeriesRequest +from .types.tensorboard_service import BatchCreateTensorboardTimeSeriesResponse +from .types.tensorboard_service import BatchReadTensorboardTimeSeriesDataRequest +from .types.tensorboard_service import BatchReadTensorboardTimeSeriesDataResponse +from .types.tensorboard_service import CreateTensorboardExperimentRequest +from .types.tensorboard_service import CreateTensorboardOperationMetadata +from .types.tensorboard_service import CreateTensorboardRequest +from .types.tensorboard_service import CreateTensorboardRunRequest +from .types.tensorboard_service import CreateTensorboardTimeSeriesRequest +from .types.tensorboard_service import DeleteTensorboardExperimentRequest +from .types.tensorboard_service import DeleteTensorboardRequest +from .types.tensorboard_service import DeleteTensorboardRunRequest +from .types.tensorboard_service import DeleteTensorboardTimeSeriesRequest +from .types.tensorboard_service import ExportTensorboardTimeSeriesDataRequest +from .types.tensorboard_service import ExportTensorboardTimeSeriesDataResponse +from .types.tensorboard_service import GetTensorboardExperimentRequest +from .types.tensorboard_service import GetTensorboardRequest +from .types.tensorboard_service import GetTensorboardRunRequest +from .types.tensorboard_service import GetTensorboardTimeSeriesRequest +from .types.tensorboard_service import ListTensorboardExperimentsRequest +from .types.tensorboard_service import ListTensorboardExperimentsResponse +from .types.tensorboard_service import ListTensorboardRunsRequest +from .types.tensorboard_service import ListTensorboardRunsResponse +from .types.tensorboard_service import ListTensorboardsRequest +from .types.tensorboard_service import ListTensorboardsResponse +from .types.tensorboard_service import ListTensorboardTimeSeriesRequest +from .types.tensorboard_service import ListTensorboardTimeSeriesResponse +from .types.tensorboard_service import ReadTensorboardBlobDataRequest +from .types.tensorboard_service import ReadTensorboardBlobDataResponse +from .types.tensorboard_service import ReadTensorboardTimeSeriesDataRequest +from .types.tensorboard_service import ReadTensorboardTimeSeriesDataResponse +from .types.tensorboard_service import UpdateTensorboardExperimentRequest +from .types.tensorboard_service import UpdateTensorboardOperationMetadata +from .types.tensorboard_service import UpdateTensorboardRequest +from .types.tensorboard_service import UpdateTensorboardRunRequest +from .types.tensorboard_service import UpdateTensorboardTimeSeriesRequest +from .types.tensorboard_service import WriteTensorboardExperimentDataRequest +from .types.tensorboard_service import WriteTensorboardExperimentDataResponse +from .types.tensorboard_service import WriteTensorboardRunDataRequest +from .types.tensorboard_service import WriteTensorboardRunDataResponse +from .types.tensorboard_time_series import TensorboardTimeSeries from .types.training_pipeline import FilterSplit from .types.training_pipeline import FractionSplit from .types.training_pipeline import InputDataConfig from .types.training_pipeline import PredefinedSplit +from .types.training_pipeline import StratifiedSplit from .types.training_pipeline import TimestampSplit from .types.training_pipeline import TrainingPipeline from .types.types import BoolArray from .types.types import DoubleArray from .types.types import Int64Array from .types.types import StringArray +from .types.unmanaged_container_model import UnmanagedContainerModel from .types.user_action_reference import UserActionReference from .types.value import Value from .types.vizier_service import AddTrialMeasurementRequest @@ -436,6 +496,7 @@ "PipelineServiceAsyncClient", "PredictionServiceAsyncClient", "SpecialistPoolServiceAsyncClient", + "TensorboardServiceAsyncClient", "VizierServiceAsyncClient", "AcceleratorType", "ActiveLearningConfig", @@ -456,6 +517,10 @@ "BatchCreateFeaturesOperationMetadata", "BatchCreateFeaturesRequest", "BatchCreateFeaturesResponse", + "BatchCreateTensorboardRunsRequest", + "BatchCreateTensorboardRunsResponse", + "BatchCreateTensorboardTimeSeriesRequest", + "BatchCreateTensorboardTimeSeriesResponse", "BatchDedicatedResources", "BatchMigrateResourcesOperationMetadata", "BatchMigrateResourcesRequest", @@ -464,8 +529,11 @@ "BatchReadFeatureValuesOperationMetadata", "BatchReadFeatureValuesRequest", "BatchReadFeatureValuesResponse", + "BatchReadTensorboardTimeSeriesDataRequest", + "BatchReadTensorboardTimeSeriesDataResponse", "BigQueryDestination", "BigQuerySource", + "BlurBaselineConfig", "BoolArray", "CancelBatchPredictionJobRequest", "CancelCustomJobRequest", @@ -510,6 +578,11 @@ "CreateSpecialistPoolOperationMetadata", "CreateSpecialistPoolRequest", "CreateStudyRequest", + "CreateTensorboardExperimentRequest", + "CreateTensorboardOperationMetadata", + "CreateTensorboardRequest", + "CreateTensorboardRunRequest", + "CreateTensorboardTimeSeriesRequest", "CreateTrainingPipelineRequest", "CreateTrialRequest", "CsvDestination", @@ -543,6 +616,10 @@ "DeletePipelineJobRequest", "DeleteSpecialistPoolRequest", "DeleteStudyRequest", + "DeleteTensorboardExperimentRequest", + "DeleteTensorboardRequest", + "DeleteTensorboardRunRequest", + "DeleteTensorboardTimeSeriesRequest", "DeleteTrainingPipelineRequest", "DeleteTrialRequest", "DeployIndexOperationMetadata", @@ -584,6 +661,8 @@ "ExportModelOperationMetadata", "ExportModelRequest", "ExportModelResponse", + "ExportTensorboardTimeSeriesDataRequest", + "ExportTensorboardTimeSeriesDataResponse", "Feature", "FeatureNoiseSigma", "FeatureSelector", @@ -623,6 +702,10 @@ "GetPipelineJobRequest", "GetSpecialistPoolRequest", "GetStudyRequest", + "GetTensorboardExperimentRequest", + "GetTensorboardRequest", + "GetTensorboardRunRequest", + "GetTensorboardTimeSeriesRequest", "GetTrainingPipelineRequest", "GetTrialRequest", "HyperparameterTuningJob", @@ -697,6 +780,14 @@ "ListSpecialistPoolsResponse", "ListStudiesRequest", "ListStudiesResponse", + "ListTensorboardExperimentsRequest", + "ListTensorboardExperimentsResponse", + "ListTensorboardRunsRequest", + "ListTensorboardRunsResponse", + "ListTensorboardTimeSeriesRequest", + "ListTensorboardTimeSeriesResponse", + "ListTensorboardsRequest", + "ListTensorboardsResponse", "ListTrainingPipelinesRequest", "ListTrainingPipelinesResponse", "ListTrialsRequest", @@ -726,6 +817,9 @@ "ModelMonitoringObjectiveConfig", "ModelMonitoringStatsAnomalies", "ModelServiceClient", + "MutateDeployedIndexOperationMetadata", + "MutateDeployedIndexRequest", + "MutateDeployedIndexResponse", "NearestNeighborSearchOperationMetadata", "PauseModelDeploymentMonitoringJobRequest", "PipelineJob", @@ -757,11 +851,16 @@ "RawPredictRequest", "ReadFeatureValuesRequest", "ReadFeatureValuesResponse", + "ReadTensorboardBlobDataRequest", + "ReadTensorboardBlobDataResponse", + "ReadTensorboardTimeSeriesDataRequest", + "ReadTensorboardTimeSeriesDataResponse", "ResourcesConsumed", "ResumeModelDeploymentMonitoringJobRequest", "SampleConfig", "SampledShapleyAttribution", "SamplingStrategy", + "Scalar", "Scheduling", "SearchFeaturesRequest", "SearchFeaturesResponse", @@ -773,6 +872,7 @@ "SpecialistPool", "SpecialistPoolServiceClient", "StopTrialRequest", + "StratifiedSplit", "StreamingReadFeatureValuesRequest", "StringArray", "Study", @@ -781,7 +881,17 @@ "SuggestTrialsRequest", "SuggestTrialsResponse", "TFRecordDestination", + "Tensorboard", + "TensorboardBlob", + "TensorboardBlobSequence", + "TensorboardExperiment", + "TensorboardRun", + "TensorboardServiceClient", + "TensorboardTensor", + "TensorboardTimeSeries", "ThresholdConfig", + "TimeSeriesData", + "TimeSeriesDataPoint", "TimestampSplit", "TrainingConfig", "TrainingPipeline", @@ -792,6 +902,7 @@ "UndeployModelOperationMetadata", "UndeployModelRequest", "UndeployModelResponse", + "UnmanagedContainerModel", "UpdateArtifactRequest", "UpdateContextRequest", "UpdateDatasetRequest", @@ -809,6 +920,11 @@ "UpdateModelRequest", "UpdateSpecialistPoolOperationMetadata", "UpdateSpecialistPoolRequest", + "UpdateTensorboardExperimentRequest", + "UpdateTensorboardOperationMetadata", + "UpdateTensorboardRequest", + "UpdateTensorboardRunRequest", + "UpdateTensorboardTimeSeriesRequest", "UploadModelOperationMetadata", "UploadModelRequest", "UploadModelResponse", @@ -816,5 +932,9 @@ "Value", "VizierServiceClient", "WorkerPoolSpec", + "WriteTensorboardExperimentDataRequest", + "WriteTensorboardExperimentDataResponse", + "WriteTensorboardRunDataRequest", + "WriteTensorboardRunDataResponse", "XraiAttribution", ) diff --git a/google/cloud/aiplatform_v1/gapic_metadata.json b/google/cloud/aiplatform_v1/gapic_metadata.json index 51e927bf9b..b7e8b7361a 100644 --- a/google/cloud/aiplatform_v1/gapic_metadata.json +++ b/google/cloud/aiplatform_v1/gapic_metadata.json @@ -481,6 +481,11 @@ "list_index_endpoints" ] }, + "MutateDeployedIndex": { + "methods": [ + "mutate_deployed_index" + ] + }, "UndeployIndex": { "methods": [ "undeploy_index" @@ -521,6 +526,11 @@ "list_index_endpoints" ] }, + "MutateDeployedIndex": { + "methods": [ + "mutate_deployed_index" + ] + }, "UndeployIndex": { "methods": [ "undeploy_index" @@ -1587,6 +1597,300 @@ } } }, + "TensorboardService": { + "clients": { + "grpc": { + "libraryClient": "TensorboardServiceClient", + "rpcs": { + "BatchCreateTensorboardRuns": { + "methods": [ + "batch_create_tensorboard_runs" + ] + }, + "BatchCreateTensorboardTimeSeries": { + "methods": [ + "batch_create_tensorboard_time_series" + ] + }, + "BatchReadTensorboardTimeSeriesData": { + "methods": [ + "batch_read_tensorboard_time_series_data" + ] + }, + "CreateTensorboard": { + "methods": [ + "create_tensorboard" + ] + }, + "CreateTensorboardExperiment": { + "methods": [ + "create_tensorboard_experiment" + ] + }, + "CreateTensorboardRun": { + "methods": [ + "create_tensorboard_run" + ] + }, + "CreateTensorboardTimeSeries": { + "methods": [ + "create_tensorboard_time_series" + ] + }, + "DeleteTensorboard": { + "methods": [ + "delete_tensorboard" + ] + }, + "DeleteTensorboardExperiment": { + "methods": [ + "delete_tensorboard_experiment" + ] + }, + "DeleteTensorboardRun": { + "methods": [ + "delete_tensorboard_run" + ] + }, + "DeleteTensorboardTimeSeries": { + "methods": [ + "delete_tensorboard_time_series" + ] + }, + "ExportTensorboardTimeSeriesData": { + "methods": [ + "export_tensorboard_time_series_data" + ] + }, + "GetTensorboard": { + "methods": [ + "get_tensorboard" + ] + }, + "GetTensorboardExperiment": { + "methods": [ + "get_tensorboard_experiment" + ] + }, + "GetTensorboardRun": { + "methods": [ + "get_tensorboard_run" + ] + }, + "GetTensorboardTimeSeries": { + "methods": [ + "get_tensorboard_time_series" + ] + }, + "ListTensorboardExperiments": { + "methods": [ + "list_tensorboard_experiments" + ] + }, + "ListTensorboardRuns": { + "methods": [ + "list_tensorboard_runs" + ] + }, + "ListTensorboardTimeSeries": { + "methods": [ + "list_tensorboard_time_series" + ] + }, + "ListTensorboards": { + "methods": [ + "list_tensorboards" + ] + }, + "ReadTensorboardBlobData": { + "methods": [ + "read_tensorboard_blob_data" + ] + }, + "ReadTensorboardTimeSeriesData": { + "methods": [ + "read_tensorboard_time_series_data" + ] + }, + "UpdateTensorboard": { + "methods": [ + "update_tensorboard" + ] + }, + "UpdateTensorboardExperiment": { + "methods": [ + "update_tensorboard_experiment" + ] + }, + "UpdateTensorboardRun": { + "methods": [ + "update_tensorboard_run" + ] + }, + "UpdateTensorboardTimeSeries": { + "methods": [ + "update_tensorboard_time_series" + ] + }, + "WriteTensorboardExperimentData": { + "methods": [ + "write_tensorboard_experiment_data" + ] + }, + "WriteTensorboardRunData": { + "methods": [ + "write_tensorboard_run_data" + ] + } + } + }, + "grpc-async": { + "libraryClient": "TensorboardServiceAsyncClient", + "rpcs": { + "BatchCreateTensorboardRuns": { + "methods": [ + "batch_create_tensorboard_runs" + ] + }, + "BatchCreateTensorboardTimeSeries": { + "methods": [ + "batch_create_tensorboard_time_series" + ] + }, + "BatchReadTensorboardTimeSeriesData": { + "methods": [ + "batch_read_tensorboard_time_series_data" + ] + }, + "CreateTensorboard": { + "methods": [ + "create_tensorboard" + ] + }, + "CreateTensorboardExperiment": { + "methods": [ + "create_tensorboard_experiment" + ] + }, + "CreateTensorboardRun": { + "methods": [ + "create_tensorboard_run" + ] + }, + "CreateTensorboardTimeSeries": { + "methods": [ + "create_tensorboard_time_series" + ] + }, + "DeleteTensorboard": { + "methods": [ + "delete_tensorboard" + ] + }, + "DeleteTensorboardExperiment": { + "methods": [ + "delete_tensorboard_experiment" + ] + }, + "DeleteTensorboardRun": { + "methods": [ + "delete_tensorboard_run" + ] + }, + "DeleteTensorboardTimeSeries": { + "methods": [ + "delete_tensorboard_time_series" + ] + }, + "ExportTensorboardTimeSeriesData": { + "methods": [ + "export_tensorboard_time_series_data" + ] + }, + "GetTensorboard": { + "methods": [ + "get_tensorboard" + ] + }, + "GetTensorboardExperiment": { + "methods": [ + "get_tensorboard_experiment" + ] + }, + "GetTensorboardRun": { + "methods": [ + "get_tensorboard_run" + ] + }, + "GetTensorboardTimeSeries": { + "methods": [ + "get_tensorboard_time_series" + ] + }, + "ListTensorboardExperiments": { + "methods": [ + "list_tensorboard_experiments" + ] + }, + "ListTensorboardRuns": { + "methods": [ + "list_tensorboard_runs" + ] + }, + "ListTensorboardTimeSeries": { + "methods": [ + "list_tensorboard_time_series" + ] + }, + "ListTensorboards": { + "methods": [ + "list_tensorboards" + ] + }, + "ReadTensorboardBlobData": { + "methods": [ + "read_tensorboard_blob_data" + ] + }, + "ReadTensorboardTimeSeriesData": { + "methods": [ + "read_tensorboard_time_series_data" + ] + }, + "UpdateTensorboard": { + "methods": [ + "update_tensorboard" + ] + }, + "UpdateTensorboardExperiment": { + "methods": [ + "update_tensorboard_experiment" + ] + }, + "UpdateTensorboardRun": { + "methods": [ + "update_tensorboard_run" + ] + }, + "UpdateTensorboardTimeSeries": { + "methods": [ + "update_tensorboard_time_series" + ] + }, + "WriteTensorboardExperimentData": { + "methods": [ + "write_tensorboard_experiment_data" + ] + }, + "WriteTensorboardRunData": { + "methods": [ + "write_tensorboard_run_data" + ] + } + } + } + } + }, "VizierService": { "clients": { "grpc": { diff --git a/google/cloud/aiplatform_v1/services/dataset_service/async_client.py b/google/cloud/aiplatform_v1/services/dataset_service/async_client.py index bc286e9d52..6a6c297f69 100644 --- a/google/cloud/aiplatform_v1/services/dataset_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/dataset_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1/services/dataset_service/client.py b/google/cloud/aiplatform_v1/services/dataset_service/client.py index 96d01fe1af..ea66e8921e 100644 --- a/google/cloud/aiplatform_v1/services/dataset_service/client.py +++ b/google/cloud/aiplatform_v1/services/dataset_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -359,8 +361,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1/services/dataset_service/transports/base.py b/google/cloud/aiplatform_v1/services/dataset_service/transports/base.py index 8dbfd9f9b7..86eb401885 100644 --- a/google/cloud/aiplatform_v1/services/dataset_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/dataset_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/dataset_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/dataset_service/transports/grpc.py index 2501386d11..f29b6bd3be 100644 --- a/google/cloud/aiplatform_v1/services/dataset_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/dataset_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/dataset_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/dataset_service/transports/grpc_asyncio.py index 1923000cdc..618a6434fa 100644 --- a/google/cloud/aiplatform_v1/services/dataset_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/dataset_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/endpoint_service/async_client.py b/google/cloud/aiplatform_v1/services/endpoint_service/async_client.py index 0249cec6ac..7ffd118709 100644 --- a/google/cloud/aiplatform_v1/services/endpoint_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/endpoint_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -188,6 +191,7 @@ async def create_endpoint( *, parent: str = None, endpoint: gca_endpoint.Endpoint = None, + endpoint_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -211,6 +215,21 @@ async def create_endpoint( This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + endpoint_id (:class:`str`): + Immutable. The ID to use for endpoint, which will become + the final component of the endpoint resource name. If + not provided, Vertex AI will generate a value for this + ID. + + This value should be 1-10 characters, and valid + characters are /[0-9]/. When using HTTP/JSON, this field + is populated based on a query string argument, such as + ``?endpoint_id=12345``. This is the fallback for fields + that are not included in either the URI or the body. + + This corresponds to the ``endpoint_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. @@ -228,7 +247,7 @@ async def create_endpoint( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, endpoint]) + has_flattened_params = any([parent, endpoint, endpoint_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -243,6 +262,8 @@ async def create_endpoint( request.parent = parent if endpoint is not None: request.endpoint = endpoint + if endpoint_id is not None: + request.endpoint_id = endpoint_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/aiplatform_v1/services/endpoint_service/client.py b/google/cloud/aiplatform_v1/services/endpoint_service/client.py index 4c546c0a4b..3f20e28f33 100644 --- a/google/cloud/aiplatform_v1/services/endpoint_service/client.py +++ b/google/cloud/aiplatform_v1/services/endpoint_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -343,8 +345,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -415,6 +424,7 @@ def create_endpoint( *, parent: str = None, endpoint: gca_endpoint.Endpoint = None, + endpoint_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -438,6 +448,21 @@ def create_endpoint( This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + endpoint_id (str): + Immutable. The ID to use for endpoint, which will become + the final component of the endpoint resource name. If + not provided, Vertex AI will generate a value for this + ID. + + This value should be 1-10 characters, and valid + characters are /[0-9]/. When using HTTP/JSON, this field + is populated based on a query string argument, such as + ``?endpoint_id=12345``. This is the fallback for fields + that are not included in either the URI or the body. + + This corresponds to the ``endpoint_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. @@ -455,7 +480,7 @@ def create_endpoint( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, endpoint]) + has_flattened_params = any([parent, endpoint, endpoint_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -474,6 +499,8 @@ def create_endpoint( request.parent = parent if endpoint is not None: request.endpoint = endpoint + if endpoint_id is not None: + request.endpoint_id = endpoint_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/aiplatform_v1/services/endpoint_service/transports/base.py b/google/cloud/aiplatform_v1/services/endpoint_service/transports/base.py index 3703c66859..b523932066 100644 --- a/google/cloud/aiplatform_v1/services/endpoint_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/endpoint_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/endpoint_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/endpoint_service/transports/grpc.py index 274f3691a2..8eff44667c 100644 --- a/google/cloud/aiplatform_v1/services/endpoint_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/endpoint_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/endpoint_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/endpoint_service/transports/grpc_asyncio.py index 168ab4281b..040b449ce2 100644 --- a/google/cloud/aiplatform_v1/services/endpoint_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/endpoint_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/async_client.py b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/async_client.py index f1885fd31e..a758e9a0fe 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, AsyncIterable, Awaitable, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.cloud.aiplatform_v1.types import featurestore_online_service from .transports.base import ( diff --git a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/client.py b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/client.py index ec77c86df9..8bbc0ab87e 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/client.py +++ b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Iterable, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.cloud.aiplatform_v1.types import featurestore_online_service from .transports.base import ( @@ -298,8 +300,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/base.py b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/base.py index 5b885dc993..88e5a03c54 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/base.py @@ -18,10 +18,10 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/grpc.py index 3d2c5b02f1..80d729714b 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/grpc.py @@ -16,8 +16,8 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/grpc_asyncio.py index 36c304acc8..b22b01939a 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/featurestore_online_serving_service/transports/grpc_asyncio.py @@ -16,8 +16,8 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/featurestore_service/async_client.py b/google/cloud/aiplatform_v1/services/featurestore_service/async_client.py index 14d2c6f5ea..4f85bb6b07 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/featurestore_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -193,6 +196,7 @@ async def create_featurestore( *, parent: str = None, featurestore: gca_featurestore.Featurestore = None, + featurestore_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -217,6 +221,21 @@ async def create_featurestore( This corresponds to the ``featurestore`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + featurestore_id (:class:`str`): + Required. The ID to use for this Featurestore, which + will become the final component of the Featurestore's + resource name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within the project and + location. + + This corresponds to the ``featurestore_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. @@ -227,7 +246,7 @@ async def create_featurestore( google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Featurestore` Vertex Feature Store provides a centralized repository for organizing, + The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Featurestore` Vertex AI Feature Store provides a centralized repository for organizing, storing, and serving ML features. The Featurestore is a top-level container for your features and their values. @@ -236,7 +255,7 @@ async def create_featurestore( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, featurestore]) + has_flattened_params = any([parent, featurestore, featurestore_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -251,6 +270,8 @@ async def create_featurestore( request.parent = parent if featurestore is not None: request.featurestore = featurestore + if featurestore_id is not None: + request.featurestore_id = featurestore_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -310,7 +331,7 @@ async def get_featurestore( Returns: google.cloud.aiplatform_v1.types.Featurestore: - Vertex Feature Store provides a + Vertex AI Feature Store provides a centralized repository for organizing, storing, and serving ML features. The Featurestore is a top-level container @@ -487,7 +508,7 @@ async def update_featurestore( google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Featurestore` Vertex Feature Store provides a centralized repository for organizing, + The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Featurestore` Vertex AI Feature Store provides a centralized repository for organizing, storing, and serving ML features. The Featurestore is a top-level container for your features and their values. @@ -656,6 +677,7 @@ async def create_entity_type( *, parent: str = None, entity_type: gca_entity_type.EntityType = None, + entity_type_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -679,6 +701,20 @@ async def create_entity_type( This corresponds to the ``entity_type`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + entity_type_id (:class:`str`): + Required. The ID to use for the EntityType, which will + become the final component of the EntityType's resource + name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within a featurestore. + + This corresponds to the ``entity_type_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. @@ -698,7 +734,7 @@ async def create_entity_type( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, entity_type]) + has_flattened_params = any([parent, entity_type, entity_type_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -713,6 +749,8 @@ async def create_entity_type( request.parent = parent if entity_type is not None: request.entity_type = entity_type + if entity_type_id is not None: + request.entity_type_id = entity_type_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -1112,6 +1150,7 @@ async def create_feature( *, parent: str = None, feature: gca_feature.Feature = None, + feature_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -1135,6 +1174,20 @@ async def create_feature( This corresponds to the ``feature`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + feature_id (:class:`str`): + Required. The ID to use for the Feature, which will + become the final component of the Feature's resource + name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within an EntityType. + + This corresponds to the ``feature_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. @@ -1153,7 +1206,7 @@ async def create_feature( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, feature]) + has_flattened_params = any([parent, feature, feature_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -1168,6 +1221,8 @@ async def create_feature( request.parent = parent if feature is not None: request.feature = feature + if feature_id is not None: + request.feature_id = feature_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/aiplatform_v1/services/featurestore_service/client.py b/google/cloud/aiplatform_v1/services/featurestore_service/client.py index b75d81c549..ea6a73b4af 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_service/client.py +++ b/google/cloud/aiplatform_v1/services/featurestore_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -343,8 +345,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -415,6 +424,7 @@ def create_featurestore( *, parent: str = None, featurestore: gca_featurestore.Featurestore = None, + featurestore_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -439,6 +449,21 @@ def create_featurestore( This corresponds to the ``featurestore`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + featurestore_id (str): + Required. The ID to use for this Featurestore, which + will become the final component of the Featurestore's + resource name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within the project and + location. + + This corresponds to the ``featurestore_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. @@ -449,7 +474,7 @@ def create_featurestore( google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Featurestore` Vertex Feature Store provides a centralized repository for organizing, + The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Featurestore` Vertex AI Feature Store provides a centralized repository for organizing, storing, and serving ML features. The Featurestore is a top-level container for your features and their values. @@ -458,7 +483,7 @@ def create_featurestore( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, featurestore]) + has_flattened_params = any([parent, featurestore, featurestore_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -477,6 +502,8 @@ def create_featurestore( request.parent = parent if featurestore is not None: request.featurestore = featurestore + if featurestore_id is not None: + request.featurestore_id = featurestore_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -532,7 +559,7 @@ def get_featurestore( Returns: google.cloud.aiplatform_v1.types.Featurestore: - Vertex Feature Store provides a + Vertex AI Feature Store provides a centralized repository for organizing, storing, and serving ML features. The Featurestore is a top-level container @@ -709,7 +736,7 @@ def update_featurestore( google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Featurestore` Vertex Feature Store provides a centralized repository for organizing, + The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Featurestore` Vertex AI Feature Store provides a centralized repository for organizing, storing, and serving ML features. The Featurestore is a top-level container for your features and their values. @@ -878,6 +905,7 @@ def create_entity_type( *, parent: str = None, entity_type: gca_entity_type.EntityType = None, + entity_type_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -901,6 +929,20 @@ def create_entity_type( This corresponds to the ``entity_type`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + entity_type_id (str): + Required. The ID to use for the EntityType, which will + become the final component of the EntityType's resource + name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within a featurestore. + + This corresponds to the ``entity_type_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. @@ -920,7 +962,7 @@ def create_entity_type( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, entity_type]) + has_flattened_params = any([parent, entity_type, entity_type_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -939,6 +981,8 @@ def create_entity_type( request.parent = parent if entity_type is not None: request.entity_type = entity_type + if entity_type_id is not None: + request.entity_type_id = entity_type_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -1334,6 +1378,7 @@ def create_feature( *, parent: str = None, feature: gca_feature.Feature = None, + feature_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -1357,6 +1402,20 @@ def create_feature( This corresponds to the ``feature`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + feature_id (str): + Required. The ID to use for the Feature, which will + become the final component of the Feature's resource + name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within an EntityType. + + This corresponds to the ``feature_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. @@ -1375,7 +1434,7 @@ def create_feature( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, feature]) + has_flattened_params = any([parent, feature, feature_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -1394,6 +1453,8 @@ def create_feature( request.parent = parent if feature is not None: request.feature = feature + if feature_id is not None: + request.feature_id = feature_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/aiplatform_v1/services/featurestore_service/transports/base.py b/google/cloud/aiplatform_v1/services/featurestore_service/transports/base.py index a8787d6ca3..f4f71d58c9 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/featurestore_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/featurestore_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/featurestore_service/transports/grpc.py index e257e3477f..45f0ed6e3b 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/featurestore_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/featurestore_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/featurestore_service/transports/grpc_asyncio.py index e968e40020..ec11a1f4b8 100644 --- a/google/cloud/aiplatform_v1/services/featurestore_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/featurestore_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/index_endpoint_service/async_client.py b/google/cloud/aiplatform_v1/services/index_endpoint_service/async_client.py index c4527cffc8..57f3b519f9 100644 --- a/google/cloud/aiplatform_v1/services/index_endpoint_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/index_endpoint_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -795,6 +798,105 @@ async def undeploy_index( # Done; return the response. return response + async def mutate_deployed_index( + self, + request: Union[index_endpoint_service.MutateDeployedIndexRequest, dict] = None, + *, + index_endpoint: str = None, + deployed_index: gca_index_endpoint.DeployedIndex = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Update an existing DeployedIndex under an + IndexEndpoint. + + Args: + request (Union[google.cloud.aiplatform_v1.types.MutateDeployedIndexRequest, dict]): + The request object. Request message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1.IndexEndpointService.MutateDeployedIndex]. + index_endpoint (:class:`str`): + Required. The name of the IndexEndpoint resource into + which to deploy an Index. Format: + ``projects/{project}/locations/{location}/indexEndpoints/{index_endpoint}`` + + This corresponds to the ``index_endpoint`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + deployed_index (:class:`google.cloud.aiplatform_v1.types.DeployedIndex`): + Required. The DeployedIndex to be updated within the + IndexEndpoint. Currently, the updatable fields are + [DeployedIndex][automatic_resources] and + [DeployedIndex][dedicated_resources] + + This corresponds to the ``deployed_index`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.aiplatform_v1.types.MutateDeployedIndexResponse` + Response message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1.IndexEndpointService.MutateDeployedIndex]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([index_endpoint, deployed_index]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = index_endpoint_service.MutateDeployedIndexRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if index_endpoint is not None: + request.index_endpoint = index_endpoint + if deployed_index is not None: + request.deployed_index = deployed_index + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.mutate_deployed_index, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("index_endpoint", request.index_endpoint),) + ), + ) + + # 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, + index_endpoint_service.MutateDeployedIndexResponse, + metadata_type=index_endpoint_service.MutateDeployedIndexOperationMetadata, + ) + + # Done; return the response. + return response + async def __aenter__(self): return self diff --git a/google/cloud/aiplatform_v1/services/index_endpoint_service/client.py b/google/cloud/aiplatform_v1/services/index_endpoint_service/client.py index 4a48cbc6a0..770a7989e4 100644 --- a/google/cloud/aiplatform_v1/services/index_endpoint_service/client.py +++ b/google/cloud/aiplatform_v1/services/index_endpoint_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -309,8 +311,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -994,6 +1003,105 @@ def undeploy_index( # Done; return the response. return response + def mutate_deployed_index( + self, + request: Union[index_endpoint_service.MutateDeployedIndexRequest, dict] = None, + *, + index_endpoint: str = None, + deployed_index: gca_index_endpoint.DeployedIndex = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gac_operation.Operation: + r"""Update an existing DeployedIndex under an + IndexEndpoint. + + Args: + request (Union[google.cloud.aiplatform_v1.types.MutateDeployedIndexRequest, dict]): + The request object. Request message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1.IndexEndpointService.MutateDeployedIndex]. + index_endpoint (str): + Required. The name of the IndexEndpoint resource into + which to deploy an Index. Format: + ``projects/{project}/locations/{location}/indexEndpoints/{index_endpoint}`` + + This corresponds to the ``index_endpoint`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + deployed_index (google.cloud.aiplatform_v1.types.DeployedIndex): + Required. The DeployedIndex to be updated within the + IndexEndpoint. Currently, the updatable fields are + [DeployedIndex][automatic_resources] and + [DeployedIndex][dedicated_resources] + + This corresponds to the ``deployed_index`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.aiplatform_v1.types.MutateDeployedIndexResponse` + Response message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1.IndexEndpointService.MutateDeployedIndex]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([index_endpoint, deployed_index]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a index_endpoint_service.MutateDeployedIndexRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, index_endpoint_service.MutateDeployedIndexRequest): + request = index_endpoint_service.MutateDeployedIndexRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if index_endpoint is not None: + request.index_endpoint = index_endpoint + if deployed_index is not None: + request.deployed_index = deployed_index + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_deployed_index] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("index_endpoint", request.index_endpoint),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = gac_operation.from_gapic( + response, + self._transport.operations_client, + index_endpoint_service.MutateDeployedIndexResponse, + metadata_type=index_endpoint_service.MutateDeployedIndexOperationMetadata, + ) + + # Done; return the response. + return response + def __enter__(self): return self diff --git a/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/base.py b/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/base.py index 3960252e4a..094ccb33c8 100644 --- a/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore @@ -154,6 +154,11 @@ def _prep_wrapped_messages(self, client_info): self.undeploy_index: gapic_v1.method.wrap_method( self.undeploy_index, default_timeout=None, client_info=client_info, ), + self.mutate_deployed_index: gapic_v1.method.wrap_method( + self.mutate_deployed_index, + default_timeout=None, + client_info=client_info, + ), } def close(self): @@ -239,5 +244,14 @@ def undeploy_index( ]: raise NotImplementedError() + @property + def mutate_deployed_index( + self, + ) -> Callable[ + [index_endpoint_service.MutateDeployedIndexRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + __all__ = ("IndexEndpointServiceTransport",) diff --git a/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/grpc.py index 400269b953..340a5d2057 100644 --- a/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -446,6 +446,35 @@ def undeploy_index( ) return self._stubs["undeploy_index"] + @property + def mutate_deployed_index( + self, + ) -> Callable[ + [index_endpoint_service.MutateDeployedIndexRequest], operations_pb2.Operation + ]: + r"""Return a callable for the mutate deployed index method over gRPC. + + Update an existing DeployedIndex under an + IndexEndpoint. + + Returns: + Callable[[~.MutateDeployedIndexRequest], + ~.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 "mutate_deployed_index" not in self._stubs: + self._stubs["mutate_deployed_index"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.IndexEndpointService/MutateDeployedIndex", + request_serializer=index_endpoint_service.MutateDeployedIndexRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["mutate_deployed_index"] + def close(self): self.grpc_channel.close() diff --git a/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/grpc_asyncio.py index 20201caef3..928f1e09e0 100644 --- a/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/index_endpoint_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -454,6 +454,36 @@ def undeploy_index( ) return self._stubs["undeploy_index"] + @property + def mutate_deployed_index( + self, + ) -> Callable[ + [index_endpoint_service.MutateDeployedIndexRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the mutate deployed index method over gRPC. + + Update an existing DeployedIndex under an + IndexEndpoint. + + Returns: + Callable[[~.MutateDeployedIndexRequest], + 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 "mutate_deployed_index" not in self._stubs: + self._stubs["mutate_deployed_index"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.IndexEndpointService/MutateDeployedIndex", + request_serializer=index_endpoint_service.MutateDeployedIndexRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["mutate_deployed_index"] + def close(self): return self.grpc_channel.close() diff --git a/google/cloud/aiplatform_v1/services/index_service/async_client.py b/google/cloud/aiplatform_v1/services/index_service/async_client.py index 410550adb3..4c46cc9e98 100644 --- a/google/cloud/aiplatform_v1/services/index_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/index_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1/services/index_service/client.py b/google/cloud/aiplatform_v1/services/index_service/client.py index 5212d5bc59..8d37766d2a 100644 --- a/google/cloud/aiplatform_v1/services/index_service/client.py +++ b/google/cloud/aiplatform_v1/services/index_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -309,8 +311,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1/services/index_service/transports/base.py b/google/cloud/aiplatform_v1/services/index_service/transports/base.py index 43852a5560..c6d5eded3b 100644 --- a/google/cloud/aiplatform_v1/services/index_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/index_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/index_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/index_service/transports/grpc.py index 3b594c3081..e0aa6a22f8 100644 --- a/google/cloud/aiplatform_v1/services/index_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/index_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/index_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/index_service/transports/grpc_asyncio.py index c31498274d..2f1880a659 100644 --- a/google/cloud/aiplatform_v1/services/index_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/index_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/job_service/async_client.py b/google/cloud/aiplatform_v1/services/job_service/async_client.py index 56a8ad2e19..00a77a8788 100644 --- a/google/cloud/aiplatform_v1/services/job_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/job_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -58,6 +61,7 @@ from google.cloud.aiplatform_v1.types import model_monitoring from google.cloud.aiplatform_v1.types import operation as gca_operation from google.cloud.aiplatform_v1.types import study +from google.cloud.aiplatform_v1.types import unmanaged_container_model from google.protobuf import duration_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore @@ -108,6 +112,8 @@ class JobServiceAsyncClient: ) network_path = staticmethod(JobServiceClient.network_path) parse_network_path = staticmethod(JobServiceClient.parse_network_path) + tensorboard_path = staticmethod(JobServiceClient.tensorboard_path) + parse_tensorboard_path = staticmethod(JobServiceClient.parse_tensorboard_path) trial_path = staticmethod(JobServiceClient.trial_path) parse_trial_path = staticmethod(JobServiceClient.parse_trial_path) common_billing_account_path = staticmethod( @@ -1969,7 +1975,7 @@ async def search_model_deployment_monitoring_stats_anomalies( should not be set. deployed_model_id (:class:`str`): Required. The DeployedModel ID of the - [google.cloud.aiplatform.master.ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. + [ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. This corresponds to the ``deployed_model_id`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/google/cloud/aiplatform_v1/services/job_service/client.py b/google/cloud/aiplatform_v1/services/job_service/client.py index 86423b1abc..91e232ef97 100644 --- a/google/cloud/aiplatform_v1/services/job_service/client.py +++ b/google/cloud/aiplatform_v1/services/job_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -62,6 +64,7 @@ from google.cloud.aiplatform_v1.types import model_monitoring from google.cloud.aiplatform_v1.types import operation as gca_operation from google.cloud.aiplatform_v1.types import study +from google.cloud.aiplatform_v1.types import unmanaged_container_model from google.protobuf import duration_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore @@ -347,6 +350,22 @@ def parse_network_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def tensorboard_path(project: str, location: str, tensorboard: str,) -> str: + """Returns a fully-qualified tensorboard string.""" + return "projects/{project}/locations/{location}/tensorboards/{tensorboard}".format( + project=project, location=location, tensorboard=tensorboard, + ) + + @staticmethod + def parse_tensorboard_path(path: str) -> Dict[str, str]: + """Parses a tensorboard path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tensorboards/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def trial_path(project: str, location: str, study: str, trial: str,) -> str: """Returns a fully-qualified trial string.""" @@ -473,8 +492,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -2310,7 +2336,7 @@ def search_model_deployment_monitoring_stats_anomalies( should not be set. deployed_model_id (str): Required. The DeployedModel ID of the - [google.cloud.aiplatform.master.ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. + [ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. This corresponds to the ``deployed_model_id`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/google/cloud/aiplatform_v1/services/job_service/transports/base.py b/google/cloud/aiplatform_v1/services/job_service/transports/base.py index 199c5d5ebc..e94b170248 100644 --- a/google/cloud/aiplatform_v1/services/job_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/job_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/job_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/job_service/transports/grpc.py index 6200d15bb7..8313d01b85 100644 --- a/google/cloud/aiplatform_v1/services/job_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/job_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/job_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/job_service/transports/grpc_asyncio.py index 8a717a0c2b..524f69d5fa 100644 --- a/google/cloud/aiplatform_v1/services/job_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/job_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/metadata_service/async_client.py b/google/cloud/aiplatform_v1/services/metadata_service/async_client.py index d71aacae41..3acff1b408 100644 --- a/google/cloud/aiplatform_v1/services/metadata_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/metadata_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1/services/metadata_service/client.py b/google/cloud/aiplatform_v1/services/metadata_service/client.py index bfb27e8dc2..d3f74607bf 100644 --- a/google/cloud/aiplatform_v1/services/metadata_service/client.py +++ b/google/cloud/aiplatform_v1/services/metadata_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -387,8 +389,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1/services/metadata_service/transports/base.py b/google/cloud/aiplatform_v1/services/metadata_service/transports/base.py index ab8b598488..1680f3f1f9 100644 --- a/google/cloud/aiplatform_v1/services/metadata_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/metadata_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/metadata_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/metadata_service/transports/grpc.py index 34c4de2422..3451898345 100644 --- a/google/cloud/aiplatform_v1/services/metadata_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/metadata_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/metadata_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/metadata_service/transports/grpc_asyncio.py index 6a0d90692f..e029a8b782 100644 --- a/google/cloud/aiplatform_v1/services/metadata_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/metadata_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/migration_service/async_client.py b/google/cloud/aiplatform_v1/services/migration_service/async_client.py index 33e5a27855..8ff44ad8bd 100644 --- a/google/cloud/aiplatform_v1/services/migration_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/migration_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1/services/migration_service/client.py b/google/cloud/aiplatform_v1/services/migration_service/client.py index 17b370d687..8e509a04a6 100644 --- a/google/cloud/aiplatform_v1/services/migration_service/client.py +++ b/google/cloud/aiplatform_v1/services/migration_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore @@ -383,8 +385,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1/services/migration_service/transports/base.py b/google/cloud/aiplatform_v1/services/migration_service/transports/base.py index e0abbd1b23..147276408a 100644 --- a/google/cloud/aiplatform_v1/services/migration_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/migration_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/migration_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/migration_service/transports/grpc.py index 0473840e00..d705ebe72c 100644 --- a/google/cloud/aiplatform_v1/services/migration_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/migration_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/migration_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/migration_service/transports/grpc_asyncio.py index 8725ec52a5..b355ae80c1 100644 --- a/google/cloud/aiplatform_v1/services/migration_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/migration_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/model_service/async_client.py b/google/cloud/aiplatform_v1/services/model_service/async_client.py index da49d2d69d..8c3caae9b2 100644 --- a/google/cloud/aiplatform_v1/services/model_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/model_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -525,8 +528,12 @@ async def delete_model( ) -> operation_async.AsyncOperation: r"""Deletes a Model. - Model can only be deleted if there are no [DeployedModels][] - created from it. + A model cannot be deleted if any + [Endpoint][google.cloud.aiplatform.v1.Endpoint] resource has a + [DeployedModel][google.cloud.aiplatform.v1.DeployedModel] based + on the model in its + [deployed_models][google.cloud.aiplatform.v1.Endpoint.deployed_models] + field. Args: request (Union[google.cloud.aiplatform_v1.types.DeleteModelRequest, dict]): @@ -620,7 +627,7 @@ async def export_model( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Exports a trained, exportable, Model to a location specified by + r"""Exports a trained, exportable Model to a location specified by the user. A Model is considered to be exportable if it has at least one [supported export format][google.cloud.aiplatform.v1.Model.supported_export_formats]. diff --git a/google/cloud/aiplatform_v1/services/model_service/client.py b/google/cloud/aiplatform_v1/services/model_service/client.py index 8e76ff9706..60bdad30c5 100644 --- a/google/cloud/aiplatform_v1/services/model_service/client.py +++ b/google/cloud/aiplatform_v1/services/model_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -369,8 +371,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -771,8 +780,12 @@ def delete_model( ) -> gac_operation.Operation: r"""Deletes a Model. - Model can only be deleted if there are no [DeployedModels][] - created from it. + A model cannot be deleted if any + [Endpoint][google.cloud.aiplatform.v1.Endpoint] resource has a + [DeployedModel][google.cloud.aiplatform.v1.DeployedModel] based + on the model in its + [deployed_models][google.cloud.aiplatform.v1.Endpoint.deployed_models] + field. Args: request (Union[google.cloud.aiplatform_v1.types.DeleteModelRequest, dict]): @@ -866,7 +879,7 @@ def export_model( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> gac_operation.Operation: - r"""Exports a trained, exportable, Model to a location specified by + r"""Exports a trained, exportable Model to a location specified by the user. A Model is considered to be exportable if it has at least one [supported export format][google.cloud.aiplatform.v1.Model.supported_export_formats]. diff --git a/google/cloud/aiplatform_v1/services/model_service/transports/base.py b/google/cloud/aiplatform_v1/services/model_service/transports/base.py index 818ba73f1a..5615336d38 100644 --- a/google/cloud/aiplatform_v1/services/model_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/model_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/model_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/model_service/transports/grpc.py index 980a1d2aa5..91751eef77 100644 --- a/google/cloud/aiplatform_v1/services/model_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/model_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -356,8 +356,12 @@ def delete_model( Deletes a Model. - Model can only be deleted if there are no [DeployedModels][] - created from it. + A model cannot be deleted if any + [Endpoint][google.cloud.aiplatform.v1.Endpoint] resource has a + [DeployedModel][google.cloud.aiplatform.v1.DeployedModel] based + on the model in its + [deployed_models][google.cloud.aiplatform.v1.Endpoint.deployed_models] + field. Returns: Callable[[~.DeleteModelRequest], @@ -383,7 +387,7 @@ def export_model( ) -> Callable[[model_service.ExportModelRequest], operations_pb2.Operation]: r"""Return a callable for the export model method over gRPC. - Exports a trained, exportable, Model to a location specified by + Exports a trained, exportable Model to a location specified by the user. A Model is considered to be exportable if it has at least one [supported export format][google.cloud.aiplatform.v1.Model.supported_export_formats]. diff --git a/google/cloud/aiplatform_v1/services/model_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/model_service/transports/grpc_asyncio.py index 5f25911385..71ae4b287e 100644 --- a/google/cloud/aiplatform_v1/services/model_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/model_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -368,8 +368,12 @@ def delete_model( Deletes a Model. - Model can only be deleted if there are no [DeployedModels][] - created from it. + A model cannot be deleted if any + [Endpoint][google.cloud.aiplatform.v1.Endpoint] resource has a + [DeployedModel][google.cloud.aiplatform.v1.DeployedModel] based + on the model in its + [deployed_models][google.cloud.aiplatform.v1.Endpoint.deployed_models] + field. Returns: Callable[[~.DeleteModelRequest], @@ -397,7 +401,7 @@ def export_model( ]: r"""Return a callable for the export model method over gRPC. - Exports a trained, exportable, Model to a location specified by + Exports a trained, exportable Model to a location specified by the user. A Model is considered to be exportable if it has at least one [supported export format][google.cloud.aiplatform.v1.Model.supported_export_formats]. diff --git a/google/cloud/aiplatform_v1/services/pipeline_service/async_client.py b/google/cloud/aiplatform_v1/services/pipeline_service/async_client.py index 5197e816ca..c13faa5438 100644 --- a/google/cloud/aiplatform_v1/services/pipeline_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/pipeline_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -52,7 +55,7 @@ class PipelineServiceAsyncClient: """A service for creating and managing Vertex AI's pipelines. This includes both ``TrainingPipeline`` resources (used for AutoML and - custom training) and ``PipelineJob`` resources (used for Vertex + custom training) and ``PipelineJob`` resources (used for Vertex AI Pipelines). """ diff --git a/google/cloud/aiplatform_v1/services/pipeline_service/client.py b/google/cloud/aiplatform_v1/services/pipeline_service/client.py index 158dbcc9a6..ee9754086e 100644 --- a/google/cloud/aiplatform_v1/services/pipeline_service/client.py +++ b/google/cloud/aiplatform_v1/services/pipeline_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -89,7 +91,7 @@ def get_transport_class(cls, label: str = None,) -> Type[PipelineServiceTranspor class PipelineServiceClient(metaclass=PipelineServiceClientMeta): """A service for creating and managing Vertex AI's pipelines. This includes both ``TrainingPipeline`` resources (used for AutoML and - custom training) and ``PipelineJob`` resources (used for Vertex + custom training) and ``PipelineJob`` resources (used for Vertex AI Pipelines). """ @@ -445,8 +447,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1/services/pipeline_service/transports/base.py b/google/cloud/aiplatform_v1/services/pipeline_service/transports/base.py index f6ccadbd1e..3da341fbb7 100644 --- a/google/cloud/aiplatform_v1/services/pipeline_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/pipeline_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/pipeline_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/pipeline_service/transports/grpc.py index 0318d07c07..87d0dafdb1 100644 --- a/google/cloud/aiplatform_v1/services/pipeline_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/pipeline_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -40,7 +40,7 @@ class PipelineServiceGrpcTransport(PipelineServiceTransport): A service for creating and managing Vertex AI's pipelines. This includes both ``TrainingPipeline`` resources (used for AutoML and - custom training) and ``PipelineJob`` resources (used for Vertex + custom training) and ``PipelineJob`` resources (used for Vertex AI Pipelines). This class defines the same methods as the primary client, so the diff --git a/google/cloud/aiplatform_v1/services/pipeline_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/pipeline_service/transports/grpc_asyncio.py index 218f7ae063..624014b258 100644 --- a/google/cloud/aiplatform_v1/services/pipeline_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/pipeline_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -41,7 +41,7 @@ class PipelineServiceGrpcAsyncIOTransport(PipelineServiceTransport): A service for creating and managing Vertex AI's pipelines. This includes both ``TrainingPipeline`` resources (used for AutoML and - custom training) and ``PipelineJob`` resources (used for Vertex + custom training) and ``PipelineJob`` resources (used for Vertex AI Pipelines). This class defines the same methods as the primary client, so the diff --git a/google/cloud/aiplatform_v1/services/prediction_service/async_client.py b/google/cloud/aiplatform_v1/services/prediction_service/async_client.py index 17e4b332ae..ef0e1a655c 100644 --- a/google/cloud/aiplatform_v1/services/prediction_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/prediction_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api import httpbody_pb2 # type: ignore from google.cloud.aiplatform_v1.types import explanation diff --git a/google/cloud/aiplatform_v1/services/prediction_service/client.py b/google/cloud/aiplatform_v1/services/prediction_service/client.py index 0d70630816..07834c79d6 100644 --- a/google/cloud/aiplatform_v1/services/prediction_service/client.py +++ b/google/cloud/aiplatform_v1/services/prediction_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api import httpbody_pb2 # type: ignore from google.cloud.aiplatform_v1.types import explanation @@ -304,8 +306,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1/services/prediction_service/transports/base.py b/google/cloud/aiplatform_v1/services/prediction_service/transports/base.py index 2d57136a4c..4a1d1706f3 100644 --- a/google/cloud/aiplatform_v1/services/prediction_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/prediction_service/transports/base.py @@ -18,10 +18,10 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/prediction_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/prediction_service/transports/grpc.py index 6f80d4b748..111c5897c5 100644 --- a/google/cloud/aiplatform_v1/services/prediction_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/prediction_service/transports/grpc.py @@ -16,8 +16,8 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/prediction_service/transports/grpc_asyncio.py index 3f995b70d9..f03d7c4aaa 100644 --- a/google/cloud/aiplatform_v1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/prediction_service/transports/grpc_asyncio.py @@ -16,8 +16,8 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/specialist_pool_service/async_client.py b/google/cloud/aiplatform_v1/services/specialist_pool_service/async_client.py index 03ab451a86..9b36163ee1 100644 --- a/google/cloud/aiplatform_v1/services/specialist_pool_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/specialist_pool_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1/services/specialist_pool_service/client.py b/google/cloud/aiplatform_v1/services/specialist_pool_service/client.py index 0ce394d45d..04030b804c 100644 --- a/google/cloud/aiplatform_v1/services/specialist_pool_service/client.py +++ b/google/cloud/aiplatform_v1/services/specialist_pool_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -298,8 +300,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/base.py b/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/base.py index 09bc6d05ad..86f7871a6f 100644 --- a/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/grpc.py index 48acc97b5e..f621f63d30 100644 --- a/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/grpc_asyncio.py index cfced9e5d5..2a45f210ca 100644 --- a/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/specialist_pool_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1/services/tensorboard_service/__init__.py b/google/cloud/aiplatform_v1/services/tensorboard_service/__init__.py new file mode 100644 index 0000000000..5a3d5fc22e --- /dev/null +++ b/google/cloud/aiplatform_v1/services/tensorboard_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import TensorboardServiceClient +from .async_client import TensorboardServiceAsyncClient + +__all__ = ( + "TensorboardServiceClient", + "TensorboardServiceAsyncClient", +) diff --git a/google/cloud/aiplatform_v1/services/tensorboard_service/async_client.py b/google/cloud/aiplatform_v1/services/tensorboard_service/async_client.py new file mode 100644 index 0000000000..3adea38fe5 --- /dev/null +++ b/google/cloud/aiplatform_v1/services/tensorboard_service/async_client.py @@ -0,0 +1,2680 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import functools +import re +from typing import Dict, AsyncIterable, Awaitable, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation as gac_operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.aiplatform_v1.services.tensorboard_service import pagers +from google.cloud.aiplatform_v1.types import encryption_spec +from google.cloud.aiplatform_v1.types import operation as gca_operation +from google.cloud.aiplatform_v1.types import tensorboard +from google.cloud.aiplatform_v1.types import tensorboard as gca_tensorboard +from google.cloud.aiplatform_v1.types import tensorboard_data +from google.cloud.aiplatform_v1.types import tensorboard_experiment +from google.cloud.aiplatform_v1.types import ( + tensorboard_experiment as gca_tensorboard_experiment, +) +from google.cloud.aiplatform_v1.types import tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_run as gca_tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_service +from google.cloud.aiplatform_v1.types import tensorboard_time_series +from google.cloud.aiplatform_v1.types import ( + tensorboard_time_series as gca_tensorboard_time_series, +) +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import TensorboardServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import TensorboardServiceGrpcAsyncIOTransport +from .client import TensorboardServiceClient + + +class TensorboardServiceAsyncClient: + """TensorboardService""" + + _client: TensorboardServiceClient + + DEFAULT_ENDPOINT = TensorboardServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = TensorboardServiceClient.DEFAULT_MTLS_ENDPOINT + + tensorboard_path = staticmethod(TensorboardServiceClient.tensorboard_path) + parse_tensorboard_path = staticmethod( + TensorboardServiceClient.parse_tensorboard_path + ) + tensorboard_experiment_path = staticmethod( + TensorboardServiceClient.tensorboard_experiment_path + ) + parse_tensorboard_experiment_path = staticmethod( + TensorboardServiceClient.parse_tensorboard_experiment_path + ) + tensorboard_run_path = staticmethod(TensorboardServiceClient.tensorboard_run_path) + parse_tensorboard_run_path = staticmethod( + TensorboardServiceClient.parse_tensorboard_run_path + ) + tensorboard_time_series_path = staticmethod( + TensorboardServiceClient.tensorboard_time_series_path + ) + parse_tensorboard_time_series_path = staticmethod( + TensorboardServiceClient.parse_tensorboard_time_series_path + ) + common_billing_account_path = staticmethod( + TensorboardServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + TensorboardServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(TensorboardServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + TensorboardServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + TensorboardServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + TensorboardServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(TensorboardServiceClient.common_project_path) + parse_common_project_path = staticmethod( + TensorboardServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(TensorboardServiceClient.common_location_path) + parse_common_location_path = staticmethod( + TensorboardServiceClient.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: + TensorboardServiceAsyncClient: The constructed client. + """ + return TensorboardServiceClient.from_service_account_info.__func__(TensorboardServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + TensorboardServiceAsyncClient: The constructed client. + """ + return TensorboardServiceClient.from_service_account_file.__func__(TensorboardServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> TensorboardServiceTransport: + """Returns the transport used by the client instance. + + Returns: + TensorboardServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial( + type(TensorboardServiceClient).get_transport_class, + type(TensorboardServiceClient), + ) + + def __init__( + self, + *, + credentials: ga_credentials.Credentials = None, + transport: Union[str, TensorboardServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the tensorboard service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.TensorboardServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = TensorboardServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + async def create_tensorboard( + self, + request: Union[tensorboard_service.CreateTensorboardRequest, dict] = None, + *, + parent: str = None, + tensorboard: gca_tensorboard.Tensorboard = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a Tensorboard. + + Args: + request (Union[google.cloud.aiplatform_v1.types.CreateTensorboardRequest, dict]): + The request object. Request message for + [TensorboardService.CreateTensorboard][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboard]. + parent (:class:`str`): + Required. The resource name of the Location to create + the Tensorboard in. Format: + ``projects/{project}/locations/{location}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard (:class:`google.cloud.aiplatform_v1.types.Tensorboard`): + Required. The Tensorboard to create. + This corresponds to the ``tensorboard`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Tensorboard` Tensorboard is a physical database that stores users' training metrics. + A default Tensorboard is provided in each region of a + GCP project. If needed users can also create extra + Tensorboards in their projects. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, tensorboard]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.CreateTensorboardRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tensorboard is not None: + request.tensorboard = tensorboard + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_tensorboard, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + gca_tensorboard.Tensorboard, + metadata_type=tensorboard_service.CreateTensorboardOperationMetadata, + ) + + # Done; return the response. + return response + + async def get_tensorboard( + self, + request: Union[tensorboard_service.GetTensorboardRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard.Tensorboard: + r"""Gets a Tensorboard. + + Args: + request (Union[google.cloud.aiplatform_v1.types.GetTensorboardRequest, dict]): + The request object. Request message for + [TensorboardService.GetTensorboard][google.cloud.aiplatform.v1.TensorboardService.GetTensorboard]. + name (:class:`str`): + Required. The name of the Tensorboard resource. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.Tensorboard: + Tensorboard is a physical database + that stores users' training metrics. A + default Tensorboard is provided in each + region of a GCP project. If needed users + can also create extra Tensorboards in + their projects. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.GetTensorboardRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_tensorboard, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def update_tensorboard( + self, + request: Union[tensorboard_service.UpdateTensorboardRequest, dict] = None, + *, + tensorboard: gca_tensorboard.Tensorboard = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates a Tensorboard. + + Args: + request (Union[google.cloud.aiplatform_v1.types.UpdateTensorboardRequest, dict]): + The request object. Request message for + [TensorboardService.UpdateTensorboard][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboard]. + tensorboard (:class:`google.cloud.aiplatform_v1.types.Tensorboard`): + Required. The Tensorboard's ``name`` field is used to + identify the Tensorboard to be updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + + This corresponds to the ``tensorboard`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Required. Field mask is used to specify the fields to be + overwritten in the Tensorboard 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 if + new values are specified. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Tensorboard` Tensorboard is a physical database that stores users' training metrics. + A default Tensorboard is provided in each region of a + GCP project. If needed users can also create extra + Tensorboards in their projects. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.UpdateTensorboardRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard is not None: + request.tensorboard = tensorboard + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_tensorboard, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard.name", request.tensorboard.name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + gca_tensorboard.Tensorboard, + metadata_type=tensorboard_service.UpdateTensorboardOperationMetadata, + ) + + # Done; return the response. + return response + + async def list_tensorboards( + self, + request: Union[tensorboard_service.ListTensorboardsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListTensorboardsAsyncPager: + r"""Lists Tensorboards in a Location. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ListTensorboardsRequest, dict]): + The request object. Request message for + [TensorboardService.ListTensorboards][google.cloud.aiplatform.v1.TensorboardService.ListTensorboards]. + parent (:class:`str`): + Required. The resource name of the Location to list + Tensorboards. 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, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ListTensorboardsAsyncPager: + Response message for + [TensorboardService.ListTensorboards][google.cloud.aiplatform.v1.TensorboardService.ListTensorboards]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.ListTensorboardsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_tensorboards, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListTensorboardsAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_tensorboard( + self, + request: Union[tensorboard_service.DeleteTensorboardRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a Tensorboard. + + Args: + request (Union[google.cloud.aiplatform_v1.types.DeleteTensorboardRequest, dict]): + The request object. Request message for + [TensorboardService.DeleteTensorboard][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboard]. + name (:class:`str`): + Required. The name of the Tensorboard to be deleted. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.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); + + } + + The JSON representation for Empty is empty JSON + object {}. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.DeleteTensorboardRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_tensorboard, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=gca_operation.DeleteOperationMetadata, + ) + + # Done; return the response. + return response + + async def create_tensorboard_experiment( + self, + request: Union[ + tensorboard_service.CreateTensorboardExperimentRequest, dict + ] = None, + *, + parent: str = None, + tensorboard_experiment: gca_tensorboard_experiment.TensorboardExperiment = None, + tensorboard_experiment_id: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_experiment.TensorboardExperiment: + r"""Creates a TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.CreateTensorboardExperimentRequest, dict]): + The request object. Request message for + [TensorboardService.CreateTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboardExperiment]. + parent (:class:`str`): + Required. The resource name of the Tensorboard to create + the TensorboardExperiment in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_experiment (:class:`google.cloud.aiplatform_v1.types.TensorboardExperiment`): + The TensorboardExperiment to create. + This corresponds to the ``tensorboard_experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_experiment_id (:class:`str`): + Required. The ID to use for the Tensorboard experiment, + which will become the final component of the Tensorboard + experiment's resource name. + + This value should be 1-128 characters, and valid + characters are /[a-z][0-9]-/. + + This corresponds to the ``tensorboard_experiment_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardExperiment: + A TensorboardExperiment is a group of + TensorboardRuns, that are typically the + results of a training job run, in a + Tensorboard. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [parent, tensorboard_experiment, tensorboard_experiment_id] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.CreateTensorboardExperimentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tensorboard_experiment is not None: + request.tensorboard_experiment = tensorboard_experiment + if tensorboard_experiment_id is not None: + request.tensorboard_experiment_id = tensorboard_experiment_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_tensorboard_experiment, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_tensorboard_experiment( + self, + request: Union[ + tensorboard_service.GetTensorboardExperimentRequest, dict + ] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_experiment.TensorboardExperiment: + r"""Gets a TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.GetTensorboardExperimentRequest, dict]): + The request object. Request message for + [TensorboardService.GetTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.GetTensorboardExperiment]. + name (:class:`str`): + Required. The name of the TensorboardExperiment + resource. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardExperiment: + A TensorboardExperiment is a group of + TensorboardRuns, that are typically the + results of a training job run, in a + Tensorboard. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.GetTensorboardExperimentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_tensorboard_experiment, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def update_tensorboard_experiment( + self, + request: Union[ + tensorboard_service.UpdateTensorboardExperimentRequest, dict + ] = None, + *, + tensorboard_experiment: gca_tensorboard_experiment.TensorboardExperiment = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_experiment.TensorboardExperiment: + r"""Updates a TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.UpdateTensorboardExperimentRequest, dict]): + The request object. Request message for + [TensorboardService.UpdateTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboardExperiment]. + tensorboard_experiment (:class:`google.cloud.aiplatform_v1.types.TensorboardExperiment`): + Required. The TensorboardExperiment's ``name`` field is + used to identify the TensorboardExperiment to be + updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``tensorboard_experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Required. Field mask is used to specify the fields to be + overwritten in the TensorboardExperiment 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 if new values are specified. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardExperiment: + A TensorboardExperiment is a group of + TensorboardRuns, that are typically the + results of a training job run, in a + Tensorboard. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_experiment, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.UpdateTensorboardExperimentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_experiment is not None: + request.tensorboard_experiment = tensorboard_experiment + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_tensorboard_experiment, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_experiment.name", request.tensorboard_experiment.name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def list_tensorboard_experiments( + self, + request: Union[ + tensorboard_service.ListTensorboardExperimentsRequest, dict + ] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListTensorboardExperimentsAsyncPager: + r"""Lists TensorboardExperiments in a Location. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ListTensorboardExperimentsRequest, dict]): + The request object. Request message for + [TensorboardService.ListTensorboardExperiments][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardExperiments]. + parent (:class:`str`): + Required. The resource name of the + Tensorboard to list + TensorboardExperiments. Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}' + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ListTensorboardExperimentsAsyncPager: + Response message for + [TensorboardService.ListTensorboardExperiments][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardExperiments]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.ListTensorboardExperimentsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_tensorboard_experiments, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListTensorboardExperimentsAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_tensorboard_experiment( + self, + request: Union[ + tensorboard_service.DeleteTensorboardExperimentRequest, dict + ] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.DeleteTensorboardExperimentRequest, dict]): + The request object. Request message for + [TensorboardService.DeleteTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboardExperiment]. + name (:class:`str`): + Required. The name of the TensorboardExperiment to be + deleted. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.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); + + } + + The JSON representation for Empty is empty JSON + object {}. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.DeleteTensorboardExperimentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_tensorboard_experiment, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=gca_operation.DeleteOperationMetadata, + ) + + # Done; return the response. + return response + + async def create_tensorboard_run( + self, + request: Union[tensorboard_service.CreateTensorboardRunRequest, dict] = None, + *, + parent: str = None, + tensorboard_run: gca_tensorboard_run.TensorboardRun = None, + tensorboard_run_id: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_run.TensorboardRun: + r"""Creates a TensorboardRun. + + Args: + request (Union[google.cloud.aiplatform_v1.types.CreateTensorboardRunRequest, dict]): + The request object. Request message for + [TensorboardService.CreateTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboardRun]. + parent (:class:`str`): + Required. The resource name of the TensorboardExperiment + to create the TensorboardRun in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_run (:class:`google.cloud.aiplatform_v1.types.TensorboardRun`): + Required. The TensorboardRun to + create. + + This corresponds to the ``tensorboard_run`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_run_id (:class:`str`): + Required. The ID to use for the Tensorboard run, which + will become the final component of the Tensorboard run's + resource name. + + This value should be 1-128 characters, and valid + characters are /[a-z][0-9]-/. + + This corresponds to the ``tensorboard_run_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardRun: + TensorboardRun maps to a specific + execution of a training job with a given + set of hyperparameter values, model + definition, dataset, etc + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, tensorboard_run, tensorboard_run_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.CreateTensorboardRunRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tensorboard_run is not None: + request.tensorboard_run = tensorboard_run + if tensorboard_run_id is not None: + request.tensorboard_run_id = tensorboard_run_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_tensorboard_run, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def batch_create_tensorboard_runs( + self, + request: Union[ + tensorboard_service.BatchCreateTensorboardRunsRequest, dict + ] = None, + *, + parent: str = None, + requests: Sequence[tensorboard_service.CreateTensorboardRunRequest] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.BatchCreateTensorboardRunsResponse: + r"""Batch create TensorboardRuns. + + Args: + request (Union[google.cloud.aiplatform_v1.types.BatchCreateTensorboardRunsRequest, dict]): + The request object. Request message for + [TensorboardService.BatchCreateTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardRuns]. + parent (:class:`str`): + Required. The resource name of the TensorboardExperiment + to create the TensorboardRuns in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + The parent field in the CreateTensorboardRunRequest + messages must match this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (:class:`Sequence[google.cloud.aiplatform_v1.types.CreateTensorboardRunRequest]`): + Required. The request message + specifying the TensorboardRuns to + create. A maximum of 1000 + TensorboardRuns can be created in a + batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.BatchCreateTensorboardRunsResponse: + Response message for + [TensorboardService.BatchCreateTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardRuns]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, requests]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.BatchCreateTensorboardRunsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_create_tensorboard_runs, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_tensorboard_run( + self, + request: Union[tensorboard_service.GetTensorboardRunRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_run.TensorboardRun: + r"""Gets a TensorboardRun. + + Args: + request (Union[google.cloud.aiplatform_v1.types.GetTensorboardRunRequest, dict]): + The request object. Request message for + [TensorboardService.GetTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.GetTensorboardRun]. + name (:class:`str`): + Required. The name of the TensorboardRun resource. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardRun: + TensorboardRun maps to a specific + execution of a training job with a given + set of hyperparameter values, model + definition, dataset, etc + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.GetTensorboardRunRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_tensorboard_run, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def update_tensorboard_run( + self, + request: Union[tensorboard_service.UpdateTensorboardRunRequest, dict] = None, + *, + tensorboard_run: gca_tensorboard_run.TensorboardRun = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_run.TensorboardRun: + r"""Updates a TensorboardRun. + + Args: + request (Union[google.cloud.aiplatform_v1.types.UpdateTensorboardRunRequest, dict]): + The request object. Request message for + [TensorboardService.UpdateTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboardRun]. + tensorboard_run (:class:`google.cloud.aiplatform_v1.types.TensorboardRun`): + Required. The TensorboardRun's ``name`` field is used to + identify the TensorboardRun to be updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``tensorboard_run`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Required. Field mask is used to specify the fields to be + overwritten in the TensorboardRun 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 if new values are specified. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardRun: + TensorboardRun maps to a specific + execution of a training job with a given + set of hyperparameter values, model + definition, dataset, etc + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_run, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.UpdateTensorboardRunRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_run is not None: + request.tensorboard_run = tensorboard_run + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_tensorboard_run, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_run.name", request.tensorboard_run.name),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def list_tensorboard_runs( + self, + request: Union[tensorboard_service.ListTensorboardRunsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListTensorboardRunsAsyncPager: + r"""Lists TensorboardRuns in a Location. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ListTensorboardRunsRequest, dict]): + The request object. Request message for + [TensorboardService.ListTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardRuns]. + parent (:class:`str`): + Required. The resource name of the + TensorboardExperiment to list + TensorboardRuns. Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}' + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ListTensorboardRunsAsyncPager: + Response message for + [TensorboardService.ListTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardRuns]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.ListTensorboardRunsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_tensorboard_runs, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListTensorboardRunsAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_tensorboard_run( + self, + request: Union[tensorboard_service.DeleteTensorboardRunRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a TensorboardRun. + + Args: + request (Union[google.cloud.aiplatform_v1.types.DeleteTensorboardRunRequest, dict]): + The request object. Request message for + [TensorboardService.DeleteTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboardRun]. + name (:class:`str`): + Required. The name of the TensorboardRun to be deleted. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.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); + + } + + The JSON representation for Empty is empty JSON + object {}. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.DeleteTensorboardRunRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_tensorboard_run, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=gca_operation.DeleteOperationMetadata, + ) + + # Done; return the response. + return response + + async def batch_create_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.BatchCreateTensorboardTimeSeriesRequest, dict + ] = None, + *, + parent: str = None, + requests: Sequence[ + tensorboard_service.CreateTensorboardTimeSeriesRequest + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.BatchCreateTensorboardTimeSeriesResponse: + r"""Batch create TensorboardTimeSeries that belong to a + TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.BatchCreateTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.BatchCreateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardTimeSeries]. + parent (:class:`str`): + Required. The resource name of the TensorboardExperiment + to create the TensorboardTimeSeries in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + The TensorboardRuns referenced by the parent fields in + the CreateTensorboardTimeSeriesRequest messages must be + sub resources of this TensorboardExperiment. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (:class:`Sequence[google.cloud.aiplatform_v1.types.CreateTensorboardTimeSeriesRequest]`): + Required. The request message + specifying the TensorboardTimeSeries to + create. A maximum of 1000 + TensorboardTimeSeries can be created in + a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.BatchCreateTensorboardTimeSeriesResponse: + Response message for + [TensorboardService.BatchCreateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardTimeSeries]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, requests]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.BatchCreateTensorboardTimeSeriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_create_tensorboard_time_series, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def create_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.CreateTensorboardTimeSeriesRequest, dict + ] = None, + *, + parent: str = None, + tensorboard_time_series: gca_tensorboard_time_series.TensorboardTimeSeries = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_time_series.TensorboardTimeSeries: + r"""Creates a TensorboardTimeSeries. + + Args: + request (Union[google.cloud.aiplatform_v1.types.CreateTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.CreateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboardTimeSeries]. + parent (:class:`str`): + Required. The resource name of the TensorboardRun to + create the TensorboardTimeSeries in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_time_series (:class:`google.cloud.aiplatform_v1.types.TensorboardTimeSeries`): + Required. The TensorboardTimeSeries + to create. + + This corresponds to the ``tensorboard_time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardTimeSeries: + TensorboardTimeSeries maps to times + series produced in training runs + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, tensorboard_time_series]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.CreateTensorboardTimeSeriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tensorboard_time_series is not None: + request.tensorboard_time_series = tensorboard_time_series + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_tensorboard_time_series, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.GetTensorboardTimeSeriesRequest, dict + ] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_time_series.TensorboardTimeSeries: + r"""Gets a TensorboardTimeSeries. + + Args: + request (Union[google.cloud.aiplatform_v1.types.GetTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.GetTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.GetTensorboardTimeSeries]. + name (:class:`str`): + Required. The name of the TensorboardTimeSeries + resource. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardTimeSeries: + TensorboardTimeSeries maps to times + series produced in training runs + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.GetTensorboardTimeSeriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_tensorboard_time_series, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def update_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.UpdateTensorboardTimeSeriesRequest, dict + ] = None, + *, + tensorboard_time_series: gca_tensorboard_time_series.TensorboardTimeSeries = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_time_series.TensorboardTimeSeries: + r"""Updates a TensorboardTimeSeries. + + Args: + request (Union[google.cloud.aiplatform_v1.types.UpdateTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.UpdateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboardTimeSeries]. + tensorboard_time_series (:class:`google.cloud.aiplatform_v1.types.TensorboardTimeSeries`): + Required. The TensorboardTimeSeries' ``name`` field is + used to identify the TensorboardTimeSeries to be + updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``tensorboard_time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Required. Field mask is used to specify the fields to be + overwritten in the TensorboardTimeSeries 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 if new values are specified. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardTimeSeries: + TensorboardTimeSeries maps to times + series produced in training runs + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_time_series, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.UpdateTensorboardTimeSeriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_time_series is not None: + request.tensorboard_time_series = tensorboard_time_series + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_tensorboard_time_series, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ( + "tensorboard_time_series.name", + request.tensorboard_time_series.name, + ), + ) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def list_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.ListTensorboardTimeSeriesRequest, dict + ] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListTensorboardTimeSeriesAsyncPager: + r"""Lists TensorboardTimeSeries in a Location. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.ListTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardTimeSeries]. + parent (:class:`str`): + Required. The resource name of the + TensorboardRun to list + TensorboardTimeSeries. Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}' + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ListTensorboardTimeSeriesAsyncPager: + Response message for + [TensorboardService.ListTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardTimeSeries]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.ListTensorboardTimeSeriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_tensorboard_time_series, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListTensorboardTimeSeriesAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.DeleteTensorboardTimeSeriesRequest, dict + ] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes a TensorboardTimeSeries. + + Args: + request (Union[google.cloud.aiplatform_v1.types.DeleteTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.DeleteTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboardTimeSeries]. + name (:class:`str`): + Required. The name of the TensorboardTimeSeries to be + deleted. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.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); + + } + + The JSON representation for Empty is empty JSON + object {}. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.DeleteTensorboardTimeSeriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_tensorboard_time_series, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=gca_operation.DeleteOperationMetadata, + ) + + # Done; return the response. + return response + + async def batch_read_tensorboard_time_series_data( + self, + request: Union[ + tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest, dict + ] = None, + *, + tensorboard: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse: + r"""Reads multiple TensorboardTimeSeries' data. The data + point number limit is 1000 for scalars, 100 for tensors + and blob references. If the number of data points stored + is less than the limit, all data will be returned. + Otherwise, that limit number of data points will be + randomly selected from this time series and returned. + + Args: + request (Union[google.cloud.aiplatform_v1.types.BatchReadTensorboardTimeSeriesDataRequest, dict]): + The request object. Request message for + [TensorboardService.BatchReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.BatchReadTensorboardTimeSeriesData]. + tensorboard (:class:`str`): + Required. The resource name of the Tensorboard + containing TensorboardTimeSeries to read data from. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}``. + The TensorboardTimeSeries referenced by + [time_series][google.cloud.aiplatform.v1.BatchReadTensorboardTimeSeriesDataRequest.time_series] + must be sub resources of this Tensorboard. + + This corresponds to the ``tensorboard`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.BatchReadTensorboardTimeSeriesDataResponse: + Response message for + [TensorboardService.BatchReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.BatchReadTensorboardTimeSeriesData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard is not None: + request.tensorboard = tensorboard + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_read_tensorboard_time_series_data, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard", request.tensorboard),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def read_tensorboard_time_series_data( + self, + request: Union[ + tensorboard_service.ReadTensorboardTimeSeriesDataRequest, dict + ] = None, + *, + tensorboard_time_series: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.ReadTensorboardTimeSeriesDataResponse: + r"""Reads a TensorboardTimeSeries' data. By default, if the number + of data points stored is less than 1000, all data will be + returned. Otherwise, 1000 data points will be randomly selected + from this time series and returned. This value can be changed by + changing max_data_points, which can't be greater than 10k. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ReadTensorboardTimeSeriesDataRequest, dict]): + The request object. Request message for + [TensorboardService.ReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardTimeSeriesData]. + tensorboard_time_series (:class:`str`): + Required. The resource name of the TensorboardTimeSeries + to read data from. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``tensorboard_time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.ReadTensorboardTimeSeriesDataResponse: + Response message for + [TensorboardService.ReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardTimeSeriesData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_time_series]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.ReadTensorboardTimeSeriesDataRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_time_series is not None: + request.tensorboard_time_series = tensorboard_time_series + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.read_tensorboard_time_series_data, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_time_series", request.tensorboard_time_series),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def read_tensorboard_blob_data( + self, + request: Union[tensorboard_service.ReadTensorboardBlobDataRequest, dict] = None, + *, + time_series: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> Awaitable[AsyncIterable[tensorboard_service.ReadTensorboardBlobDataResponse]]: + r"""Gets bytes of TensorboardBlobs. + This is to allow reading blob data stored in consumer + project's Cloud Storage bucket without users having to + obtain Cloud Storage access permission. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ReadTensorboardBlobDataRequest, dict]): + The request object. Request message for + [TensorboardService.ReadTensorboardBlobData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardBlobData]. + time_series (:class:`str`): + Required. The resource name of the TensorboardTimeSeries + to list Blobs. Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}' + + This corresponds to the ``time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + AsyncIterable[google.cloud.aiplatform_v1.types.ReadTensorboardBlobDataResponse]: + Response message for + [TensorboardService.ReadTensorboardBlobData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardBlobData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([time_series]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.ReadTensorboardBlobDataRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if time_series is not None: + request.time_series = time_series + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.read_tensorboard_blob_data, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("time_series", request.time_series),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def write_tensorboard_experiment_data( + self, + request: Union[ + tensorboard_service.WriteTensorboardExperimentDataRequest, dict + ] = None, + *, + tensorboard_experiment: str = None, + write_run_data_requests: Sequence[ + tensorboard_service.WriteTensorboardRunDataRequest + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.WriteTensorboardExperimentDataResponse: + r"""Write time series data points of multiple + TensorboardTimeSeries in multiple TensorboardRun's. If + any data fail to be ingested, an error will be returned. + + Args: + request (Union[google.cloud.aiplatform_v1.types.WriteTensorboardExperimentDataRequest, dict]): + The request object. Request message for + [TensorboardService.WriteTensorboardExperimentData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardExperimentData]. + tensorboard_experiment (:class:`str`): + Required. The resource name of the TensorboardExperiment + to write data to. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``tensorboard_experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + write_run_data_requests (:class:`Sequence[google.cloud.aiplatform_v1.types.WriteTensorboardRunDataRequest]`): + Required. Requests containing per-run + TensorboardTimeSeries data to write. + + This corresponds to the ``write_run_data_requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.WriteTensorboardExperimentDataResponse: + Response message for + [TensorboardService.WriteTensorboardExperimentData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardExperimentData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_experiment, write_run_data_requests]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.WriteTensorboardExperimentDataRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_experiment is not None: + request.tensorboard_experiment = tensorboard_experiment + if write_run_data_requests: + request.write_run_data_requests.extend(write_run_data_requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.write_tensorboard_experiment_data, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_experiment", request.tensorboard_experiment),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def write_tensorboard_run_data( + self, + request: Union[tensorboard_service.WriteTensorboardRunDataRequest, dict] = None, + *, + tensorboard_run: str = None, + time_series_data: Sequence[tensorboard_data.TimeSeriesData] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.WriteTensorboardRunDataResponse: + r"""Write time series data points into multiple + TensorboardTimeSeries under a TensorboardRun. If any + data fail to be ingested, an error will be returned. + + Args: + request (Union[google.cloud.aiplatform_v1.types.WriteTensorboardRunDataRequest, dict]): + The request object. Request message for + [TensorboardService.WriteTensorboardRunData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardRunData]. + tensorboard_run (:class:`str`): + Required. The resource name of the TensorboardRun to + write data to. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``tensorboard_run`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + time_series_data (:class:`Sequence[google.cloud.aiplatform_v1.types.TimeSeriesData]`): + Required. The TensorboardTimeSeries + data to write. Values with in a time + series are indexed by their step value. + Repeated writes to the same step will + overwrite the existing value for that + step. + The upper limit of data points per write + request is 5000. + + This corresponds to the ``time_series_data`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.WriteTensorboardRunDataResponse: + Response message for + [TensorboardService.WriteTensorboardRunData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardRunData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_run, time_series_data]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.WriteTensorboardRunDataRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_run is not None: + request.tensorboard_run = tensorboard_run + if time_series_data: + request.time_series_data.extend(time_series_data) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.write_tensorboard_run_data, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_run", request.tensorboard_run),) + ), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def export_tensorboard_time_series_data( + self, + request: Union[ + tensorboard_service.ExportTensorboardTimeSeriesDataRequest, dict + ] = None, + *, + tensorboard_time_series: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ExportTensorboardTimeSeriesDataAsyncPager: + r"""Exports a TensorboardTimeSeries' data. Data is + returned in paginated responses. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataRequest, dict]): + The request object. Request message for + [TensorboardService.ExportTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ExportTensorboardTimeSeriesData]. + tensorboard_time_series (:class:`str`): + Required. The resource name of the TensorboardTimeSeries + to export data from. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``tensorboard_time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ExportTensorboardTimeSeriesDataAsyncPager: + Response message for + [TensorboardService.ExportTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ExportTensorboardTimeSeriesData]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_time_series]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = tensorboard_service.ExportTensorboardTimeSeriesDataRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_time_series is not None: + request.tensorboard_time_series = tensorboard_time_series + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.export_tensorboard_time_series_data, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_time_series", request.tensorboard_time_series),) + ), + ) + + # 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.ExportTensorboardTimeSeriesDataAsyncPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-aiplatform", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("TensorboardServiceAsyncClient",) diff --git a/google/cloud/aiplatform_v1/services/tensorboard_service/client.py b/google/cloud/aiplatform_v1/services/tensorboard_service/client.py new file mode 100644 index 0000000000..d8d9c54010 --- /dev/null +++ b/google/cloud/aiplatform_v1/services/tensorboard_service/client.py @@ -0,0 +1,3003 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +import os +import re +from typing import Dict, Optional, Iterable, Sequence, Tuple, Type, Union +import pkg_resources + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation as gac_operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.aiplatform_v1.services.tensorboard_service import pagers +from google.cloud.aiplatform_v1.types import encryption_spec +from google.cloud.aiplatform_v1.types import operation as gca_operation +from google.cloud.aiplatform_v1.types import tensorboard +from google.cloud.aiplatform_v1.types import tensorboard as gca_tensorboard +from google.cloud.aiplatform_v1.types import tensorboard_data +from google.cloud.aiplatform_v1.types import tensorboard_experiment +from google.cloud.aiplatform_v1.types import ( + tensorboard_experiment as gca_tensorboard_experiment, +) +from google.cloud.aiplatform_v1.types import tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_run as gca_tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_service +from google.cloud.aiplatform_v1.types import tensorboard_time_series +from google.cloud.aiplatform_v1.types import ( + tensorboard_time_series as gca_tensorboard_time_series, +) +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import TensorboardServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import TensorboardServiceGrpcTransport +from .transports.grpc_asyncio import TensorboardServiceGrpcAsyncIOTransport + + +class TensorboardServiceClientMeta(type): + """Metaclass for the TensorboardService 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[TensorboardServiceTransport]] + _transport_registry["grpc"] = TensorboardServiceGrpcTransport + _transport_registry["grpc_asyncio"] = TensorboardServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, label: str = None, + ) -> Type[TensorboardServiceTransport]: + """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 TensorboardServiceClient(metaclass=TensorboardServiceClientMeta): + """TensorboardService""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "aiplatform.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + TensorboardServiceClient: 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: + TensorboardServiceClient: 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) -> TensorboardServiceTransport: + """Returns the transport used by the client instance. + + Returns: + TensorboardServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def tensorboard_path(project: str, location: str, tensorboard: str,) -> str: + """Returns a fully-qualified tensorboard string.""" + return "projects/{project}/locations/{location}/tensorboards/{tensorboard}".format( + project=project, location=location, tensorboard=tensorboard, + ) + + @staticmethod + def parse_tensorboard_path(path: str) -> Dict[str, str]: + """Parses a tensorboard path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tensorboards/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def tensorboard_experiment_path( + project: str, location: str, tensorboard: str, experiment: str, + ) -> str: + """Returns a fully-qualified tensorboard_experiment string.""" + return "projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}".format( + project=project, + location=location, + tensorboard=tensorboard, + experiment=experiment, + ) + + @staticmethod + def parse_tensorboard_experiment_path(path: str) -> Dict[str, str]: + """Parses a tensorboard_experiment path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tensorboards/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def tensorboard_run_path( + project: str, location: str, tensorboard: str, experiment: str, run: str, + ) -> str: + """Returns a fully-qualified tensorboard_run string.""" + return "projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}".format( + project=project, + location=location, + tensorboard=tensorboard, + experiment=experiment, + run=run, + ) + + @staticmethod + def parse_tensorboard_run_path(path: str) -> Dict[str, str]: + """Parses a tensorboard_run path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tensorboards/(?P.+?)/experiments/(?P.+?)/runs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def tensorboard_time_series_path( + project: str, + location: str, + tensorboard: str, + experiment: str, + run: str, + time_series: str, + ) -> str: + """Returns a fully-qualified tensorboard_time_series string.""" + return "projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}".format( + project=project, + location=location, + tensorboard=tensorboard, + experiment=experiment, + run=run, + time_series=time_series, + ) + + @staticmethod + def parse_tensorboard_time_series_path(path: str) -> Dict[str, str]: + """Parses a tensorboard_time_series path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tensorboards/(?P.+?)/experiments/(?P.+?)/runs/(?P.+?)/timeSeries/(?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 {} + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, TensorboardServiceTransport, None] = None, + client_options: Optional[client_options_lib.ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the tensorboard service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, TensorboardServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + + # Create SSL credentials for mutual TLS if needed. + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" + ) + + client_cert_source_func = None + is_mtls = False + if use_client_cert: + if client_options.client_cert_source: + is_mtls = True + client_cert_source_func = client_options.client_cert_source + else: + is_mtls = mtls.has_default_client_cert_source() + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + else: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_env == "never": + api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, TensorboardServiceTransport): + # transport is a TensorboardServiceTransport instance. + if credentials or client_options.credentials_file: + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + ) + + def create_tensorboard( + self, + request: Union[tensorboard_service.CreateTensorboardRequest, dict] = None, + *, + parent: str = None, + tensorboard: gca_tensorboard.Tensorboard = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gac_operation.Operation: + r"""Creates a Tensorboard. + + Args: + request (Union[google.cloud.aiplatform_v1.types.CreateTensorboardRequest, dict]): + The request object. Request message for + [TensorboardService.CreateTensorboard][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboard]. + parent (str): + Required. The resource name of the Location to create + the Tensorboard in. Format: + ``projects/{project}/locations/{location}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard (google.cloud.aiplatform_v1.types.Tensorboard): + Required. The Tensorboard to create. + This corresponds to the ``tensorboard`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Tensorboard` Tensorboard is a physical database that stores users' training metrics. + A default Tensorboard is provided in each region of a + GCP project. If needed users can also create extra + Tensorboards in their projects. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, tensorboard]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.CreateTensorboardRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.CreateTensorboardRequest): + request = tensorboard_service.CreateTensorboardRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tensorboard is not None: + request.tensorboard = tensorboard + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_tensorboard] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = gac_operation.from_gapic( + response, + self._transport.operations_client, + gca_tensorboard.Tensorboard, + metadata_type=tensorboard_service.CreateTensorboardOperationMetadata, + ) + + # Done; return the response. + return response + + def get_tensorboard( + self, + request: Union[tensorboard_service.GetTensorboardRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard.Tensorboard: + r"""Gets a Tensorboard. + + Args: + request (Union[google.cloud.aiplatform_v1.types.GetTensorboardRequest, dict]): + The request object. Request message for + [TensorboardService.GetTensorboard][google.cloud.aiplatform.v1.TensorboardService.GetTensorboard]. + name (str): + Required. The name of the Tensorboard resource. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.Tensorboard: + Tensorboard is a physical database + that stores users' training metrics. A + default Tensorboard is provided in each + region of a GCP project. If needed users + can also create extra Tensorboards in + their projects. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.GetTensorboardRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.GetTensorboardRequest): + request = tensorboard_service.GetTensorboardRequest(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_tensorboard] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def update_tensorboard( + self, + request: Union[tensorboard_service.UpdateTensorboardRequest, dict] = None, + *, + tensorboard: gca_tensorboard.Tensorboard = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gac_operation.Operation: + r"""Updates a Tensorboard. + + Args: + request (Union[google.cloud.aiplatform_v1.types.UpdateTensorboardRequest, dict]): + The request object. Request message for + [TensorboardService.UpdateTensorboard][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboard]. + tensorboard (google.cloud.aiplatform_v1.types.Tensorboard): + Required. The Tensorboard's ``name`` field is used to + identify the Tensorboard to be updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + + This corresponds to the ``tensorboard`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Field mask is used to specify the fields to be + overwritten in the Tensorboard 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 if + new values are specified. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.aiplatform_v1.types.Tensorboard` Tensorboard is a physical database that stores users' training metrics. + A default Tensorboard is provided in each region of a + GCP project. If needed users can also create extra + Tensorboards in their projects. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.UpdateTensorboardRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.UpdateTensorboardRequest): + request = tensorboard_service.UpdateTensorboardRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard is not None: + request.tensorboard = tensorboard + 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_tensorboard] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard.name", request.tensorboard.name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = gac_operation.from_gapic( + response, + self._transport.operations_client, + gca_tensorboard.Tensorboard, + metadata_type=tensorboard_service.UpdateTensorboardOperationMetadata, + ) + + # Done; return the response. + return response + + def list_tensorboards( + self, + request: Union[tensorboard_service.ListTensorboardsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListTensorboardsPager: + r"""Lists Tensorboards in a Location. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ListTensorboardsRequest, dict]): + The request object. Request message for + [TensorboardService.ListTensorboards][google.cloud.aiplatform.v1.TensorboardService.ListTensorboards]. + parent (str): + Required. The resource name of the Location to list + Tensorboards. 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, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ListTensorboardsPager: + Response message for + [TensorboardService.ListTensorboards][google.cloud.aiplatform.v1.TensorboardService.ListTensorboards]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.ListTensorboardsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.ListTensorboardsRequest): + request = tensorboard_service.ListTensorboardsRequest(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_tensorboards] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListTensorboardsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_tensorboard( + self, + request: Union[tensorboard_service.DeleteTensorboardRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gac_operation.Operation: + r"""Deletes a Tensorboard. + + Args: + request (Union[google.cloud.aiplatform_v1.types.DeleteTensorboardRequest, dict]): + The request object. Request message for + [TensorboardService.DeleteTensorboard][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboard]. + name (str): + Required. The name of the Tensorboard to be deleted. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.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); + + } + + The JSON representation for Empty is empty JSON + object {}. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.DeleteTensorboardRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.DeleteTensorboardRequest): + request = tensorboard_service.DeleteTensorboardRequest(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_tensorboard] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = gac_operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=gca_operation.DeleteOperationMetadata, + ) + + # Done; return the response. + return response + + def create_tensorboard_experiment( + self, + request: Union[ + tensorboard_service.CreateTensorboardExperimentRequest, dict + ] = None, + *, + parent: str = None, + tensorboard_experiment: gca_tensorboard_experiment.TensorboardExperiment = None, + tensorboard_experiment_id: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_experiment.TensorboardExperiment: + r"""Creates a TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.CreateTensorboardExperimentRequest, dict]): + The request object. Request message for + [TensorboardService.CreateTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboardExperiment]. + parent (str): + Required. The resource name of the Tensorboard to create + the TensorboardExperiment in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_experiment (google.cloud.aiplatform_v1.types.TensorboardExperiment): + The TensorboardExperiment to create. + This corresponds to the ``tensorboard_experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_experiment_id (str): + Required. The ID to use for the Tensorboard experiment, + which will become the final component of the Tensorboard + experiment's resource name. + + This value should be 1-128 characters, and valid + characters are /[a-z][0-9]-/. + + This corresponds to the ``tensorboard_experiment_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardExperiment: + A TensorboardExperiment is a group of + TensorboardRuns, that are typically the + results of a training job run, in a + Tensorboard. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any( + [parent, tensorboard_experiment, tensorboard_experiment_id] + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.CreateTensorboardExperimentRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.CreateTensorboardExperimentRequest + ): + request = tensorboard_service.CreateTensorboardExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tensorboard_experiment is not None: + request.tensorboard_experiment = tensorboard_experiment + if tensorboard_experiment_id is not None: + request.tensorboard_experiment_id = tensorboard_experiment_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_tensorboard_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_tensorboard_experiment( + self, + request: Union[ + tensorboard_service.GetTensorboardExperimentRequest, dict + ] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_experiment.TensorboardExperiment: + r"""Gets a TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.GetTensorboardExperimentRequest, dict]): + The request object. Request message for + [TensorboardService.GetTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.GetTensorboardExperiment]. + name (str): + Required. The name of the TensorboardExperiment + resource. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardExperiment: + A TensorboardExperiment is a group of + TensorboardRuns, that are typically the + results of a training job run, in a + Tensorboard. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.GetTensorboardExperimentRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.GetTensorboardExperimentRequest): + request = tensorboard_service.GetTensorboardExperimentRequest(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_tensorboard_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def update_tensorboard_experiment( + self, + request: Union[ + tensorboard_service.UpdateTensorboardExperimentRequest, dict + ] = None, + *, + tensorboard_experiment: gca_tensorboard_experiment.TensorboardExperiment = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_experiment.TensorboardExperiment: + r"""Updates a TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.UpdateTensorboardExperimentRequest, dict]): + The request object. Request message for + [TensorboardService.UpdateTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboardExperiment]. + tensorboard_experiment (google.cloud.aiplatform_v1.types.TensorboardExperiment): + Required. The TensorboardExperiment's ``name`` field is + used to identify the TensorboardExperiment to be + updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``tensorboard_experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Field mask is used to specify the fields to be + overwritten in the TensorboardExperiment 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 if new values are specified. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardExperiment: + A TensorboardExperiment is a group of + TensorboardRuns, that are typically the + results of a training job run, in a + Tensorboard. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_experiment, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.UpdateTensorboardExperimentRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.UpdateTensorboardExperimentRequest + ): + request = tensorboard_service.UpdateTensorboardExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_experiment is not None: + request.tensorboard_experiment = tensorboard_experiment + 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_tensorboard_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_experiment.name", request.tensorboard_experiment.name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def list_tensorboard_experiments( + self, + request: Union[ + tensorboard_service.ListTensorboardExperimentsRequest, dict + ] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListTensorboardExperimentsPager: + r"""Lists TensorboardExperiments in a Location. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ListTensorboardExperimentsRequest, dict]): + The request object. Request message for + [TensorboardService.ListTensorboardExperiments][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardExperiments]. + parent (str): + Required. The resource name of the + Tensorboard to list + TensorboardExperiments. Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}' + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ListTensorboardExperimentsPager: + Response message for + [TensorboardService.ListTensorboardExperiments][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardExperiments]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.ListTensorboardExperimentsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.ListTensorboardExperimentsRequest + ): + request = tensorboard_service.ListTensorboardExperimentsRequest(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_tensorboard_experiments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListTensorboardExperimentsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_tensorboard_experiment( + self, + request: Union[ + tensorboard_service.DeleteTensorboardExperimentRequest, dict + ] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gac_operation.Operation: + r"""Deletes a TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.DeleteTensorboardExperimentRequest, dict]): + The request object. Request message for + [TensorboardService.DeleteTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboardExperiment]. + name (str): + Required. The name of the TensorboardExperiment to be + deleted. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.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); + + } + + The JSON representation for Empty is empty JSON + object {}. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.DeleteTensorboardExperimentRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.DeleteTensorboardExperimentRequest + ): + request = tensorboard_service.DeleteTensorboardExperimentRequest(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_tensorboard_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = gac_operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=gca_operation.DeleteOperationMetadata, + ) + + # Done; return the response. + return response + + def create_tensorboard_run( + self, + request: Union[tensorboard_service.CreateTensorboardRunRequest, dict] = None, + *, + parent: str = None, + tensorboard_run: gca_tensorboard_run.TensorboardRun = None, + tensorboard_run_id: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_run.TensorboardRun: + r"""Creates a TensorboardRun. + + Args: + request (Union[google.cloud.aiplatform_v1.types.CreateTensorboardRunRequest, dict]): + The request object. Request message for + [TensorboardService.CreateTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboardRun]. + parent (str): + Required. The resource name of the TensorboardExperiment + to create the TensorboardRun in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_run (google.cloud.aiplatform_v1.types.TensorboardRun): + Required. The TensorboardRun to + create. + + This corresponds to the ``tensorboard_run`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_run_id (str): + Required. The ID to use for the Tensorboard run, which + will become the final component of the Tensorboard run's + resource name. + + This value should be 1-128 characters, and valid + characters are /[a-z][0-9]-/. + + This corresponds to the ``tensorboard_run_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardRun: + TensorboardRun maps to a specific + execution of a training job with a given + set of hyperparameter values, model + definition, dataset, etc + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, tensorboard_run, tensorboard_run_id]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.CreateTensorboardRunRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.CreateTensorboardRunRequest): + request = tensorboard_service.CreateTensorboardRunRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tensorboard_run is not None: + request.tensorboard_run = tensorboard_run + if tensorboard_run_id is not None: + request.tensorboard_run_id = tensorboard_run_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_tensorboard_run] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def batch_create_tensorboard_runs( + self, + request: Union[ + tensorboard_service.BatchCreateTensorboardRunsRequest, dict + ] = None, + *, + parent: str = None, + requests: Sequence[tensorboard_service.CreateTensorboardRunRequest] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.BatchCreateTensorboardRunsResponse: + r"""Batch create TensorboardRuns. + + Args: + request (Union[google.cloud.aiplatform_v1.types.BatchCreateTensorboardRunsRequest, dict]): + The request object. Request message for + [TensorboardService.BatchCreateTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardRuns]. + parent (str): + Required. The resource name of the TensorboardExperiment + to create the TensorboardRuns in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + The parent field in the CreateTensorboardRunRequest + messages must match this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (Sequence[google.cloud.aiplatform_v1.types.CreateTensorboardRunRequest]): + Required. The request message + specifying the TensorboardRuns to + create. A maximum of 1000 + TensorboardRuns can be created in a + batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.BatchCreateTensorboardRunsResponse: + Response message for + [TensorboardService.BatchCreateTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardRuns]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, requests]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.BatchCreateTensorboardRunsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.BatchCreateTensorboardRunsRequest + ): + request = tensorboard_service.BatchCreateTensorboardRunsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_create_tensorboard_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),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_tensorboard_run( + self, + request: Union[tensorboard_service.GetTensorboardRunRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_run.TensorboardRun: + r"""Gets a TensorboardRun. + + Args: + request (Union[google.cloud.aiplatform_v1.types.GetTensorboardRunRequest, dict]): + The request object. Request message for + [TensorboardService.GetTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.GetTensorboardRun]. + name (str): + Required. The name of the TensorboardRun resource. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardRun: + TensorboardRun maps to a specific + execution of a training job with a given + set of hyperparameter values, model + definition, dataset, etc + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.GetTensorboardRunRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.GetTensorboardRunRequest): + request = tensorboard_service.GetTensorboardRunRequest(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_tensorboard_run] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def update_tensorboard_run( + self, + request: Union[tensorboard_service.UpdateTensorboardRunRequest, dict] = None, + *, + tensorboard_run: gca_tensorboard_run.TensorboardRun = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_run.TensorboardRun: + r"""Updates a TensorboardRun. + + Args: + request (Union[google.cloud.aiplatform_v1.types.UpdateTensorboardRunRequest, dict]): + The request object. Request message for + [TensorboardService.UpdateTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboardRun]. + tensorboard_run (google.cloud.aiplatform_v1.types.TensorboardRun): + Required. The TensorboardRun's ``name`` field is used to + identify the TensorboardRun to be updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``tensorboard_run`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Field mask is used to specify the fields to be + overwritten in the TensorboardRun 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 if new values are specified. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardRun: + TensorboardRun maps to a specific + execution of a training job with a given + set of hyperparameter values, model + definition, dataset, etc + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_run, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.UpdateTensorboardRunRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.UpdateTensorboardRunRequest): + request = tensorboard_service.UpdateTensorboardRunRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_run is not None: + request.tensorboard_run = tensorboard_run + 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_tensorboard_run] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_run.name", request.tensorboard_run.name),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def list_tensorboard_runs( + self, + request: Union[tensorboard_service.ListTensorboardRunsRequest, dict] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListTensorboardRunsPager: + r"""Lists TensorboardRuns in a Location. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ListTensorboardRunsRequest, dict]): + The request object. Request message for + [TensorboardService.ListTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardRuns]. + parent (str): + Required. The resource name of the + TensorboardExperiment to list + TensorboardRuns. Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}' + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ListTensorboardRunsPager: + Response message for + [TensorboardService.ListTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardRuns]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.ListTensorboardRunsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.ListTensorboardRunsRequest): + request = tensorboard_service.ListTensorboardRunsRequest(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_tensorboard_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),)), + ) + + # 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.ListTensorboardRunsPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_tensorboard_run( + self, + request: Union[tensorboard_service.DeleteTensorboardRunRequest, dict] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gac_operation.Operation: + r"""Deletes a TensorboardRun. + + Args: + request (Union[google.cloud.aiplatform_v1.types.DeleteTensorboardRunRequest, dict]): + The request object. Request message for + [TensorboardService.DeleteTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboardRun]. + name (str): + Required. The name of the TensorboardRun to be deleted. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.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); + + } + + The JSON representation for Empty is empty JSON + object {}. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.DeleteTensorboardRunRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.DeleteTensorboardRunRequest): + request = tensorboard_service.DeleteTensorboardRunRequest(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_tensorboard_run] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = gac_operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=gca_operation.DeleteOperationMetadata, + ) + + # Done; return the response. + return response + + def batch_create_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.BatchCreateTensorboardTimeSeriesRequest, dict + ] = None, + *, + parent: str = None, + requests: Sequence[ + tensorboard_service.CreateTensorboardTimeSeriesRequest + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.BatchCreateTensorboardTimeSeriesResponse: + r"""Batch create TensorboardTimeSeries that belong to a + TensorboardExperiment. + + Args: + request (Union[google.cloud.aiplatform_v1.types.BatchCreateTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.BatchCreateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardTimeSeries]. + parent (str): + Required. The resource name of the TensorboardExperiment + to create the TensorboardTimeSeries in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + The TensorboardRuns referenced by the parent fields in + the CreateTensorboardTimeSeriesRequest messages must be + sub resources of this TensorboardExperiment. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (Sequence[google.cloud.aiplatform_v1.types.CreateTensorboardTimeSeriesRequest]): + Required. The request message + specifying the TensorboardTimeSeries to + create. A maximum of 1000 + TensorboardTimeSeries can be created in + a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.BatchCreateTensorboardTimeSeriesResponse: + Response message for + [TensorboardService.BatchCreateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardTimeSeries]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, requests]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.BatchCreateTensorboardTimeSeriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.BatchCreateTensorboardTimeSeriesRequest + ): + request = tensorboard_service.BatchCreateTensorboardTimeSeriesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_create_tensorboard_time_series + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def create_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.CreateTensorboardTimeSeriesRequest, dict + ] = None, + *, + parent: str = None, + tensorboard_time_series: gca_tensorboard_time_series.TensorboardTimeSeries = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_time_series.TensorboardTimeSeries: + r"""Creates a TensorboardTimeSeries. + + Args: + request (Union[google.cloud.aiplatform_v1.types.CreateTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.CreateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboardTimeSeries]. + parent (str): + Required. The resource name of the TensorboardRun to + create the TensorboardTimeSeries in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tensorboard_time_series (google.cloud.aiplatform_v1.types.TensorboardTimeSeries): + Required. The TensorboardTimeSeries + to create. + + This corresponds to the ``tensorboard_time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardTimeSeries: + TensorboardTimeSeries maps to times + series produced in training runs + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, tensorboard_time_series]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.CreateTensorboardTimeSeriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.CreateTensorboardTimeSeriesRequest + ): + request = tensorboard_service.CreateTensorboardTimeSeriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tensorboard_time_series is not None: + request.tensorboard_time_series = tensorboard_time_series + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_tensorboard_time_series + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.GetTensorboardTimeSeriesRequest, dict + ] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_time_series.TensorboardTimeSeries: + r"""Gets a TensorboardTimeSeries. + + Args: + request (Union[google.cloud.aiplatform_v1.types.GetTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.GetTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.GetTensorboardTimeSeries]. + name (str): + Required. The name of the TensorboardTimeSeries + resource. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardTimeSeries: + TensorboardTimeSeries maps to times + series produced in training runs + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.GetTensorboardTimeSeriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.GetTensorboardTimeSeriesRequest): + request = tensorboard_service.GetTensorboardTimeSeriesRequest(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_tensorboard_time_series + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def update_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.UpdateTensorboardTimeSeriesRequest, dict + ] = None, + *, + tensorboard_time_series: gca_tensorboard_time_series.TensorboardTimeSeries = None, + update_mask: field_mask_pb2.FieldMask = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gca_tensorboard_time_series.TensorboardTimeSeries: + r"""Updates a TensorboardTimeSeries. + + Args: + request (Union[google.cloud.aiplatform_v1.types.UpdateTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.UpdateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboardTimeSeries]. + tensorboard_time_series (google.cloud.aiplatform_v1.types.TensorboardTimeSeries): + Required. The TensorboardTimeSeries' ``name`` field is + used to identify the TensorboardTimeSeries to be + updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``tensorboard_time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Field mask is used to specify the fields to be + overwritten in the TensorboardTimeSeries 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 if new values are specified. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.TensorboardTimeSeries: + TensorboardTimeSeries maps to times + series produced in training runs + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_time_series, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.UpdateTensorboardTimeSeriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.UpdateTensorboardTimeSeriesRequest + ): + request = tensorboard_service.UpdateTensorboardTimeSeriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_time_series is not None: + request.tensorboard_time_series = tensorboard_time_series + 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_tensorboard_time_series + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ( + "tensorboard_time_series.name", + request.tensorboard_time_series.name, + ), + ) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def list_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.ListTensorboardTimeSeriesRequest, dict + ] = None, + *, + parent: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListTensorboardTimeSeriesPager: + r"""Lists TensorboardTimeSeries in a Location. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.ListTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardTimeSeries]. + parent (str): + Required. The resource name of the + TensorboardRun to list + TensorboardTimeSeries. Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}' + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ListTensorboardTimeSeriesPager: + Response message for + [TensorboardService.ListTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardTimeSeries]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.ListTensorboardTimeSeriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.ListTensorboardTimeSeriesRequest + ): + request = tensorboard_service.ListTensorboardTimeSeriesRequest(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_tensorboard_time_series + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListTensorboardTimeSeriesPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_tensorboard_time_series( + self, + request: Union[ + tensorboard_service.DeleteTensorboardTimeSeriesRequest, dict + ] = None, + *, + name: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gac_operation.Operation: + r"""Deletes a TensorboardTimeSeries. + + Args: + request (Union[google.cloud.aiplatform_v1.types.DeleteTensorboardTimeSeriesRequest, dict]): + The request object. Request message for + [TensorboardService.DeleteTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboardTimeSeries]. + name (str): + Required. The name of the TensorboardTimeSeries to be + deleted. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.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); + + } + + The JSON representation for Empty is empty JSON + object {}. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.DeleteTensorboardTimeSeriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.DeleteTensorboardTimeSeriesRequest + ): + request = tensorboard_service.DeleteTensorboardTimeSeriesRequest(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_tensorboard_time_series + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = gac_operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=gca_operation.DeleteOperationMetadata, + ) + + # Done; return the response. + return response + + def batch_read_tensorboard_time_series_data( + self, + request: Union[ + tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest, dict + ] = None, + *, + tensorboard: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse: + r"""Reads multiple TensorboardTimeSeries' data. The data + point number limit is 1000 for scalars, 100 for tensors + and blob references. If the number of data points stored + is less than the limit, all data will be returned. + Otherwise, that limit number of data points will be + randomly selected from this time series and returned. + + Args: + request (Union[google.cloud.aiplatform_v1.types.BatchReadTensorboardTimeSeriesDataRequest, dict]): + The request object. Request message for + [TensorboardService.BatchReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.BatchReadTensorboardTimeSeriesData]. + tensorboard (str): + Required. The resource name of the Tensorboard + containing TensorboardTimeSeries to read data from. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}``. + The TensorboardTimeSeries referenced by + [time_series][google.cloud.aiplatform.v1.BatchReadTensorboardTimeSeriesDataRequest.time_series] + must be sub resources of this Tensorboard. + + This corresponds to the ``tensorboard`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.BatchReadTensorboardTimeSeriesDataResponse: + Response message for + [TensorboardService.BatchReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.BatchReadTensorboardTimeSeriesData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest + ): + request = tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard is not None: + request.tensorboard = tensorboard + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_read_tensorboard_time_series_data + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard", request.tensorboard),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def read_tensorboard_time_series_data( + self, + request: Union[ + tensorboard_service.ReadTensorboardTimeSeriesDataRequest, dict + ] = None, + *, + tensorboard_time_series: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.ReadTensorboardTimeSeriesDataResponse: + r"""Reads a TensorboardTimeSeries' data. By default, if the number + of data points stored is less than 1000, all data will be + returned. Otherwise, 1000 data points will be randomly selected + from this time series and returned. This value can be changed by + changing max_data_points, which can't be greater than 10k. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ReadTensorboardTimeSeriesDataRequest, dict]): + The request object. Request message for + [TensorboardService.ReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardTimeSeriesData]. + tensorboard_time_series (str): + Required. The resource name of the TensorboardTimeSeries + to read data from. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``tensorboard_time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.ReadTensorboardTimeSeriesDataResponse: + Response message for + [TensorboardService.ReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardTimeSeriesData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_time_series]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.ReadTensorboardTimeSeriesDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.ReadTensorboardTimeSeriesDataRequest + ): + request = tensorboard_service.ReadTensorboardTimeSeriesDataRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_time_series is not None: + request.tensorboard_time_series = tensorboard_time_series + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.read_tensorboard_time_series_data + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_time_series", request.tensorboard_time_series),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def read_tensorboard_blob_data( + self, + request: Union[tensorboard_service.ReadTensorboardBlobDataRequest, dict] = None, + *, + time_series: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> Iterable[tensorboard_service.ReadTensorboardBlobDataResponse]: + r"""Gets bytes of TensorboardBlobs. + This is to allow reading blob data stored in consumer + project's Cloud Storage bucket without users having to + obtain Cloud Storage access permission. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ReadTensorboardBlobDataRequest, dict]): + The request object. Request message for + [TensorboardService.ReadTensorboardBlobData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardBlobData]. + time_series (str): + Required. The resource name of the TensorboardTimeSeries + to list Blobs. Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}' + + This corresponds to the ``time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + Iterable[google.cloud.aiplatform_v1.types.ReadTensorboardBlobDataResponse]: + Response message for + [TensorboardService.ReadTensorboardBlobData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardBlobData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([time_series]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.ReadTensorboardBlobDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.ReadTensorboardBlobDataRequest): + request = tensorboard_service.ReadTensorboardBlobDataRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if time_series is not None: + request.time_series = time_series + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.read_tensorboard_blob_data + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("time_series", request.time_series),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def write_tensorboard_experiment_data( + self, + request: Union[ + tensorboard_service.WriteTensorboardExperimentDataRequest, dict + ] = None, + *, + tensorboard_experiment: str = None, + write_run_data_requests: Sequence[ + tensorboard_service.WriteTensorboardRunDataRequest + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.WriteTensorboardExperimentDataResponse: + r"""Write time series data points of multiple + TensorboardTimeSeries in multiple TensorboardRun's. If + any data fail to be ingested, an error will be returned. + + Args: + request (Union[google.cloud.aiplatform_v1.types.WriteTensorboardExperimentDataRequest, dict]): + The request object. Request message for + [TensorboardService.WriteTensorboardExperimentData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardExperimentData]. + tensorboard_experiment (str): + Required. The resource name of the TensorboardExperiment + to write data to. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + + This corresponds to the ``tensorboard_experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + write_run_data_requests (Sequence[google.cloud.aiplatform_v1.types.WriteTensorboardRunDataRequest]): + Required. Requests containing per-run + TensorboardTimeSeries data to write. + + This corresponds to the ``write_run_data_requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.WriteTensorboardExperimentDataResponse: + Response message for + [TensorboardService.WriteTensorboardExperimentData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardExperimentData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_experiment, write_run_data_requests]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.WriteTensorboardExperimentDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.WriteTensorboardExperimentDataRequest + ): + request = tensorboard_service.WriteTensorboardExperimentDataRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_experiment is not None: + request.tensorboard_experiment = tensorboard_experiment + if write_run_data_requests is not None: + request.write_run_data_requests = write_run_data_requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.write_tensorboard_experiment_data + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_experiment", request.tensorboard_experiment),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def write_tensorboard_run_data( + self, + request: Union[tensorboard_service.WriteTensorboardRunDataRequest, dict] = None, + *, + tensorboard_run: str = None, + time_series_data: Sequence[tensorboard_data.TimeSeriesData] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> tensorboard_service.WriteTensorboardRunDataResponse: + r"""Write time series data points into multiple + TensorboardTimeSeries under a TensorboardRun. If any + data fail to be ingested, an error will be returned. + + Args: + request (Union[google.cloud.aiplatform_v1.types.WriteTensorboardRunDataRequest, dict]): + The request object. Request message for + [TensorboardService.WriteTensorboardRunData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardRunData]. + tensorboard_run (str): + Required. The resource name of the TensorboardRun to + write data to. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + + This corresponds to the ``tensorboard_run`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + time_series_data (Sequence[google.cloud.aiplatform_v1.types.TimeSeriesData]): + Required. The TensorboardTimeSeries + data to write. Values with in a time + series are indexed by their step value. + Repeated writes to the same step will + overwrite the existing value for that + step. + The upper limit of data points per write + request is 5000. + + This corresponds to the ``time_series_data`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.types.WriteTensorboardRunDataResponse: + Response message for + [TensorboardService.WriteTensorboardRunData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardRunData]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_run, time_series_data]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.WriteTensorboardRunDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, tensorboard_service.WriteTensorboardRunDataRequest): + request = tensorboard_service.WriteTensorboardRunDataRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_run is not None: + request.tensorboard_run = tensorboard_run + if time_series_data is not None: + request.time_series_data = time_series_data + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.write_tensorboard_run_data + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_run", request.tensorboard_run),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def export_tensorboard_time_series_data( + self, + request: Union[ + tensorboard_service.ExportTensorboardTimeSeriesDataRequest, dict + ] = None, + *, + tensorboard_time_series: str = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ExportTensorboardTimeSeriesDataPager: + r"""Exports a TensorboardTimeSeries' data. Data is + returned in paginated responses. + + Args: + request (Union[google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataRequest, dict]): + The request object. Request message for + [TensorboardService.ExportTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ExportTensorboardTimeSeriesData]. + tensorboard_time_series (str): + Required. The resource name of the TensorboardTimeSeries + to export data from. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + + This corresponds to the ``tensorboard_time_series`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.aiplatform_v1.services.tensorboard_service.pagers.ExportTensorboardTimeSeriesDataPager: + Response message for + [TensorboardService.ExportTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ExportTensorboardTimeSeriesData]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([tensorboard_time_series]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a tensorboard_service.ExportTensorboardTimeSeriesDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance( + request, tensorboard_service.ExportTensorboardTimeSeriesDataRequest + ): + request = tensorboard_service.ExportTensorboardTimeSeriesDataRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tensorboard_time_series is not None: + request.tensorboard_time_series = tensorboard_time_series + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.export_tensorboard_time_series_data + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_time_series", request.tensorboard_time_series),) + ), + ) + + # 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.ExportTensorboardTimeSeriesDataPager( + method=rpc, request=request, response=response, metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-aiplatform", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +__all__ = ("TensorboardServiceClient",) diff --git a/google/cloud/aiplatform_v1/services/tensorboard_service/pagers.py b/google/cloud/aiplatform_v1/services/tensorboard_service/pagers.py new file mode 100644 index 0000000000..150562a694 --- /dev/null +++ b/google/cloud/aiplatform_v1/services/tensorboard_service/pagers.py @@ -0,0 +1,698 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Sequence, + Tuple, + Optional, + Iterator, +) + +from google.cloud.aiplatform_v1.types import tensorboard +from google.cloud.aiplatform_v1.types import tensorboard_data +from google.cloud.aiplatform_v1.types import tensorboard_experiment +from google.cloud.aiplatform_v1.types import tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_service +from google.cloud.aiplatform_v1.types import tensorboard_time_series + + +class ListTensorboardsPager: + """A pager for iterating through ``list_tensorboards`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ListTensorboardsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``tensorboards`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListTensorboards`` requests and continue to iterate + through the ``tensorboards`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ListTensorboardsResponse` + 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[..., tensorboard_service.ListTensorboardsResponse], + request: tensorboard_service.ListTensorboardsRequest, + response: tensorboard_service.ListTensorboardsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ListTensorboardsRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ListTensorboardsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ListTensorboardsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[tensorboard_service.ListTensorboardsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[tensorboard.Tensorboard]: + for page in self.pages: + yield from page.tensorboards + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListTensorboardsAsyncPager: + """A pager for iterating through ``list_tensorboards`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ListTensorboardsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``tensorboards`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListTensorboards`` requests and continue to iterate + through the ``tensorboards`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ListTensorboardsResponse` + 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[tensorboard_service.ListTensorboardsResponse]], + request: tensorboard_service.ListTensorboardsRequest, + response: tensorboard_service.ListTensorboardsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ListTensorboardsRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ListTensorboardsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ListTensorboardsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[tensorboard_service.ListTensorboardsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[tensorboard.Tensorboard]: + async def async_generator(): + async for page in self.pages: + for response in page.tensorboards: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListTensorboardExperimentsPager: + """A pager for iterating through ``list_tensorboard_experiments`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ListTensorboardExperimentsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``tensorboard_experiments`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListTensorboardExperiments`` requests and continue to iterate + through the ``tensorboard_experiments`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ListTensorboardExperimentsResponse` + 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[..., tensorboard_service.ListTensorboardExperimentsResponse], + request: tensorboard_service.ListTensorboardExperimentsRequest, + response: tensorboard_service.ListTensorboardExperimentsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ListTensorboardExperimentsRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ListTensorboardExperimentsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ListTensorboardExperimentsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[tensorboard_service.ListTensorboardExperimentsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[tensorboard_experiment.TensorboardExperiment]: + for page in self.pages: + yield from page.tensorboard_experiments + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListTensorboardExperimentsAsyncPager: + """A pager for iterating through ``list_tensorboard_experiments`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ListTensorboardExperimentsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``tensorboard_experiments`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListTensorboardExperiments`` requests and continue to iterate + through the ``tensorboard_experiments`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ListTensorboardExperimentsResponse` + 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[tensorboard_service.ListTensorboardExperimentsResponse] + ], + request: tensorboard_service.ListTensorboardExperimentsRequest, + response: tensorboard_service.ListTensorboardExperimentsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ListTensorboardExperimentsRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ListTensorboardExperimentsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ListTensorboardExperimentsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[tensorboard_service.ListTensorboardExperimentsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[tensorboard_experiment.TensorboardExperiment]: + async def async_generator(): + async for page in self.pages: + for response in page.tensorboard_experiments: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListTensorboardRunsPager: + """A pager for iterating through ``list_tensorboard_runs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ListTensorboardRunsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``tensorboard_runs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListTensorboardRuns`` requests and continue to iterate + through the ``tensorboard_runs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ListTensorboardRunsResponse` + 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[..., tensorboard_service.ListTensorboardRunsResponse], + request: tensorboard_service.ListTensorboardRunsRequest, + response: tensorboard_service.ListTensorboardRunsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ListTensorboardRunsRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ListTensorboardRunsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ListTensorboardRunsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[tensorboard_service.ListTensorboardRunsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[tensorboard_run.TensorboardRun]: + for page in self.pages: + yield from page.tensorboard_runs + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListTensorboardRunsAsyncPager: + """A pager for iterating through ``list_tensorboard_runs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ListTensorboardRunsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``tensorboard_runs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListTensorboardRuns`` requests and continue to iterate + through the ``tensorboard_runs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ListTensorboardRunsResponse` + 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[tensorboard_service.ListTensorboardRunsResponse] + ], + request: tensorboard_service.ListTensorboardRunsRequest, + response: tensorboard_service.ListTensorboardRunsResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ListTensorboardRunsRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ListTensorboardRunsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ListTensorboardRunsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[tensorboard_service.ListTensorboardRunsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[tensorboard_run.TensorboardRun]: + async def async_generator(): + async for page in self.pages: + for response in page.tensorboard_runs: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListTensorboardTimeSeriesPager: + """A pager for iterating through ``list_tensorboard_time_series`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``tensorboard_time_series`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListTensorboardTimeSeries`` requests and continue to iterate + through the ``tensorboard_time_series`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesResponse` + 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[..., tensorboard_service.ListTensorboardTimeSeriesResponse], + request: tensorboard_service.ListTensorboardTimeSeriesRequest, + response: tensorboard_service.ListTensorboardTimeSeriesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ListTensorboardTimeSeriesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[tensorboard_service.ListTensorboardTimeSeriesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[tensorboard_time_series.TensorboardTimeSeries]: + for page in self.pages: + yield from page.tensorboard_time_series + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListTensorboardTimeSeriesAsyncPager: + """A pager for iterating through ``list_tensorboard_time_series`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``tensorboard_time_series`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListTensorboardTimeSeries`` requests and continue to iterate + through the ``tensorboard_time_series`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesResponse` + 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[tensorboard_service.ListTensorboardTimeSeriesResponse] + ], + request: tensorboard_service.ListTensorboardTimeSeriesRequest, + response: tensorboard_service.ListTensorboardTimeSeriesResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ListTensorboardTimeSeriesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ListTensorboardTimeSeriesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[tensorboard_service.ListTensorboardTimeSeriesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[tensorboard_time_series.TensorboardTimeSeries]: + async def async_generator(): + async for page in self.pages: + for response in page.tensorboard_time_series: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ExportTensorboardTimeSeriesDataPager: + """A pager for iterating through ``export_tensorboard_time_series_data`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataResponse` object, and + provides an ``__iter__`` method to iterate through its + ``time_series_data_points`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ExportTensorboardTimeSeriesData`` requests and continue to iterate + through the ``time_series_data_points`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataResponse` + 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[ + ..., tensorboard_service.ExportTensorboardTimeSeriesDataResponse + ], + request: tensorboard_service.ExportTensorboardTimeSeriesDataRequest, + response: tensorboard_service.ExportTensorboardTimeSeriesDataResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ExportTensorboardTimeSeriesDataRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[tensorboard_service.ExportTensorboardTimeSeriesDataResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[tensorboard_data.TimeSeriesDataPoint]: + for page in self.pages: + yield from page.time_series_data_points + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ExportTensorboardTimeSeriesDataAsyncPager: + """A pager for iterating through ``export_tensorboard_time_series_data`` requests. + + This class thinly wraps an initial + :class:`google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``time_series_data_points`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ExportTensorboardTimeSeriesData`` requests and continue to iterate + through the ``time_series_data_points`` field on the + corresponding responses. + + All the usual :class:`google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataResponse` + 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[tensorboard_service.ExportTensorboardTimeSeriesDataResponse] + ], + request: tensorboard_service.ExportTensorboardTimeSeriesDataRequest, + response: tensorboard_service.ExportTensorboardTimeSeriesDataResponse, + *, + metadata: Sequence[Tuple[str, str]] = () + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataRequest): + The initial request object. + response (google.cloud.aiplatform_v1.types.ExportTensorboardTimeSeriesDataResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = tensorboard_service.ExportTensorboardTimeSeriesDataRequest( + request + ) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[tensorboard_service.ExportTensorboardTimeSeriesDataResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + + def __aiter__(self) -> AsyncIterator[tensorboard_data.TimeSeriesDataPoint]: + async def async_generator(): + async for page in self.pages: + for response in page.time_series_data_points: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/cloud/aiplatform_v1/services/tensorboard_service/transports/__init__.py b/google/cloud/aiplatform_v1/services/tensorboard_service/transports/__init__.py new file mode 100644 index 0000000000..50612ea154 --- /dev/null +++ b/google/cloud/aiplatform_v1/services/tensorboard_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from typing import Dict, Type + +from .base import TensorboardServiceTransport +from .grpc import TensorboardServiceGrpcTransport +from .grpc_asyncio import TensorboardServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[TensorboardServiceTransport]] +_transport_registry["grpc"] = TensorboardServiceGrpcTransport +_transport_registry["grpc_asyncio"] = TensorboardServiceGrpcAsyncIOTransport + +__all__ = ( + "TensorboardServiceTransport", + "TensorboardServiceGrpcTransport", + "TensorboardServiceGrpcAsyncIOTransport", +) diff --git a/google/cloud/aiplatform_v1/services/tensorboard_service/transports/base.py b/google/cloud/aiplatform_v1/services/tensorboard_service/transports/base.py new file mode 100644 index 0000000000..af7f8f6d7a --- /dev/null +++ b/google/cloud/aiplatform_v1/services/tensorboard_service/transports/base.py @@ -0,0 +1,599 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import pkg_resources + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.aiplatform_v1.types import tensorboard +from google.cloud.aiplatform_v1.types import tensorboard_experiment +from google.cloud.aiplatform_v1.types import ( + tensorboard_experiment as gca_tensorboard_experiment, +) +from google.cloud.aiplatform_v1.types import tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_run as gca_tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_service +from google.cloud.aiplatform_v1.types import tensorboard_time_series +from google.cloud.aiplatform_v1.types import ( + tensorboard_time_series as gca_tensorboard_time_series, +) +from google.longrunning import operations_pb2 # type: ignore + +try: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution( + "google-cloud-aiplatform", + ).version, + ) +except pkg_resources.DistributionNotFound: + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + + +class TensorboardServiceTransport(abc.ABC): + """Abstract transport class for TensorboardService.""" + + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + ) + + DEFAULT_HOST: str = "aiplatform.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + ) + + elif credentials is None: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr(service_account.Credentials, "with_always_use_jwt_access") + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_tensorboard: gapic_v1.method.wrap_method( + self.create_tensorboard, default_timeout=None, client_info=client_info, + ), + self.get_tensorboard: gapic_v1.method.wrap_method( + self.get_tensorboard, default_timeout=None, client_info=client_info, + ), + self.update_tensorboard: gapic_v1.method.wrap_method( + self.update_tensorboard, default_timeout=None, client_info=client_info, + ), + self.list_tensorboards: gapic_v1.method.wrap_method( + self.list_tensorboards, default_timeout=None, client_info=client_info, + ), + self.delete_tensorboard: gapic_v1.method.wrap_method( + self.delete_tensorboard, default_timeout=None, client_info=client_info, + ), + self.create_tensorboard_experiment: gapic_v1.method.wrap_method( + self.create_tensorboard_experiment, + default_timeout=None, + client_info=client_info, + ), + self.get_tensorboard_experiment: gapic_v1.method.wrap_method( + self.get_tensorboard_experiment, + default_timeout=None, + client_info=client_info, + ), + self.update_tensorboard_experiment: gapic_v1.method.wrap_method( + self.update_tensorboard_experiment, + default_timeout=None, + client_info=client_info, + ), + self.list_tensorboard_experiments: gapic_v1.method.wrap_method( + self.list_tensorboard_experiments, + default_timeout=None, + client_info=client_info, + ), + self.delete_tensorboard_experiment: gapic_v1.method.wrap_method( + self.delete_tensorboard_experiment, + default_timeout=None, + client_info=client_info, + ), + self.create_tensorboard_run: gapic_v1.method.wrap_method( + self.create_tensorboard_run, + default_timeout=None, + client_info=client_info, + ), + self.batch_create_tensorboard_runs: gapic_v1.method.wrap_method( + self.batch_create_tensorboard_runs, + default_timeout=None, + client_info=client_info, + ), + self.get_tensorboard_run: gapic_v1.method.wrap_method( + self.get_tensorboard_run, default_timeout=None, client_info=client_info, + ), + self.update_tensorboard_run: gapic_v1.method.wrap_method( + self.update_tensorboard_run, + default_timeout=None, + client_info=client_info, + ), + self.list_tensorboard_runs: gapic_v1.method.wrap_method( + self.list_tensorboard_runs, + default_timeout=None, + client_info=client_info, + ), + self.delete_tensorboard_run: gapic_v1.method.wrap_method( + self.delete_tensorboard_run, + default_timeout=None, + client_info=client_info, + ), + self.batch_create_tensorboard_time_series: gapic_v1.method.wrap_method( + self.batch_create_tensorboard_time_series, + default_timeout=None, + client_info=client_info, + ), + self.create_tensorboard_time_series: gapic_v1.method.wrap_method( + self.create_tensorboard_time_series, + default_timeout=None, + client_info=client_info, + ), + self.get_tensorboard_time_series: gapic_v1.method.wrap_method( + self.get_tensorboard_time_series, + default_timeout=None, + client_info=client_info, + ), + self.update_tensorboard_time_series: gapic_v1.method.wrap_method( + self.update_tensorboard_time_series, + default_timeout=None, + client_info=client_info, + ), + self.list_tensorboard_time_series: gapic_v1.method.wrap_method( + self.list_tensorboard_time_series, + default_timeout=None, + client_info=client_info, + ), + self.delete_tensorboard_time_series: gapic_v1.method.wrap_method( + self.delete_tensorboard_time_series, + default_timeout=None, + client_info=client_info, + ), + self.batch_read_tensorboard_time_series_data: gapic_v1.method.wrap_method( + self.batch_read_tensorboard_time_series_data, + default_timeout=None, + client_info=client_info, + ), + self.read_tensorboard_time_series_data: gapic_v1.method.wrap_method( + self.read_tensorboard_time_series_data, + default_timeout=None, + client_info=client_info, + ), + self.read_tensorboard_blob_data: gapic_v1.method.wrap_method( + self.read_tensorboard_blob_data, + default_timeout=None, + client_info=client_info, + ), + self.write_tensorboard_experiment_data: gapic_v1.method.wrap_method( + self.write_tensorboard_experiment_data, + default_timeout=None, + client_info=client_info, + ), + self.write_tensorboard_run_data: gapic_v1.method.wrap_method( + self.write_tensorboard_run_data, + default_timeout=None, + client_info=client_info, + ), + self.export_tensorboard_time_series_data: gapic_v1.method.wrap_method( + self.export_tensorboard_time_series_data, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def create_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def get_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardRequest], + Union[tensorboard.Tensorboard, Awaitable[tensorboard.Tensorboard]], + ]: + raise NotImplementedError() + + @property + def update_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def list_tensorboards( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardsRequest], + Union[ + tensorboard_service.ListTensorboardsResponse, + Awaitable[tensorboard_service.ListTensorboardsResponse], + ], + ]: + raise NotImplementedError() + + @property + def delete_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def create_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardExperimentRequest], + Union[ + gca_tensorboard_experiment.TensorboardExperiment, + Awaitable[gca_tensorboard_experiment.TensorboardExperiment], + ], + ]: + raise NotImplementedError() + + @property + def get_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardExperimentRequest], + Union[ + tensorboard_experiment.TensorboardExperiment, + Awaitable[tensorboard_experiment.TensorboardExperiment], + ], + ]: + raise NotImplementedError() + + @property + def update_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardExperimentRequest], + Union[ + gca_tensorboard_experiment.TensorboardExperiment, + Awaitable[gca_tensorboard_experiment.TensorboardExperiment], + ], + ]: + raise NotImplementedError() + + @property + def list_tensorboard_experiments( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardExperimentsRequest], + Union[ + tensorboard_service.ListTensorboardExperimentsResponse, + Awaitable[tensorboard_service.ListTensorboardExperimentsResponse], + ], + ]: + raise NotImplementedError() + + @property + def delete_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardExperimentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def create_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardRunRequest], + Union[ + gca_tensorboard_run.TensorboardRun, + Awaitable[gca_tensorboard_run.TensorboardRun], + ], + ]: + raise NotImplementedError() + + @property + def batch_create_tensorboard_runs( + self, + ) -> Callable[ + [tensorboard_service.BatchCreateTensorboardRunsRequest], + Union[ + tensorboard_service.BatchCreateTensorboardRunsResponse, + Awaitable[tensorboard_service.BatchCreateTensorboardRunsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardRunRequest], + Union[ + tensorboard_run.TensorboardRun, Awaitable[tensorboard_run.TensorboardRun] + ], + ]: + raise NotImplementedError() + + @property + def update_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardRunRequest], + Union[ + gca_tensorboard_run.TensorboardRun, + Awaitable[gca_tensorboard_run.TensorboardRun], + ], + ]: + raise NotImplementedError() + + @property + def list_tensorboard_runs( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardRunsRequest], + Union[ + tensorboard_service.ListTensorboardRunsResponse, + Awaitable[tensorboard_service.ListTensorboardRunsResponse], + ], + ]: + raise NotImplementedError() + + @property + def delete_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardRunRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def batch_create_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.BatchCreateTensorboardTimeSeriesRequest], + Union[ + tensorboard_service.BatchCreateTensorboardTimeSeriesResponse, + Awaitable[tensorboard_service.BatchCreateTensorboardTimeSeriesResponse], + ], + ]: + raise NotImplementedError() + + @property + def create_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardTimeSeriesRequest], + Union[ + gca_tensorboard_time_series.TensorboardTimeSeries, + Awaitable[gca_tensorboard_time_series.TensorboardTimeSeries], + ], + ]: + raise NotImplementedError() + + @property + def get_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardTimeSeriesRequest], + Union[ + tensorboard_time_series.TensorboardTimeSeries, + Awaitable[tensorboard_time_series.TensorboardTimeSeries], + ], + ]: + raise NotImplementedError() + + @property + def update_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardTimeSeriesRequest], + Union[ + gca_tensorboard_time_series.TensorboardTimeSeries, + Awaitable[gca_tensorboard_time_series.TensorboardTimeSeries], + ], + ]: + raise NotImplementedError() + + @property + def list_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardTimeSeriesRequest], + Union[ + tensorboard_service.ListTensorboardTimeSeriesResponse, + Awaitable[tensorboard_service.ListTensorboardTimeSeriesResponse], + ], + ]: + raise NotImplementedError() + + @property + def delete_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardTimeSeriesRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def batch_read_tensorboard_time_series_data( + self, + ) -> Callable[ + [tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest], + Union[ + tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse, + Awaitable[tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse], + ], + ]: + raise NotImplementedError() + + @property + def read_tensorboard_time_series_data( + self, + ) -> Callable[ + [tensorboard_service.ReadTensorboardTimeSeriesDataRequest], + Union[ + tensorboard_service.ReadTensorboardTimeSeriesDataResponse, + Awaitable[tensorboard_service.ReadTensorboardTimeSeriesDataResponse], + ], + ]: + raise NotImplementedError() + + @property + def read_tensorboard_blob_data( + self, + ) -> Callable[ + [tensorboard_service.ReadTensorboardBlobDataRequest], + Union[ + tensorboard_service.ReadTensorboardBlobDataResponse, + Awaitable[tensorboard_service.ReadTensorboardBlobDataResponse], + ], + ]: + raise NotImplementedError() + + @property + def write_tensorboard_experiment_data( + self, + ) -> Callable[ + [tensorboard_service.WriteTensorboardExperimentDataRequest], + Union[ + tensorboard_service.WriteTensorboardExperimentDataResponse, + Awaitable[tensorboard_service.WriteTensorboardExperimentDataResponse], + ], + ]: + raise NotImplementedError() + + @property + def write_tensorboard_run_data( + self, + ) -> Callable[ + [tensorboard_service.WriteTensorboardRunDataRequest], + Union[ + tensorboard_service.WriteTensorboardRunDataResponse, + Awaitable[tensorboard_service.WriteTensorboardRunDataResponse], + ], + ]: + raise NotImplementedError() + + @property + def export_tensorboard_time_series_data( + self, + ) -> Callable[ + [tensorboard_service.ExportTensorboardTimeSeriesDataRequest], + Union[ + tensorboard_service.ExportTensorboardTimeSeriesDataResponse, + Awaitable[tensorboard_service.ExportTensorboardTimeSeriesDataResponse], + ], + ]: + raise NotImplementedError() + + +__all__ = ("TensorboardServiceTransport",) diff --git a/google/cloud/aiplatform_v1/services/tensorboard_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/tensorboard_service/transports/grpc.py new file mode 100644 index 0000000000..84b28c5e56 --- /dev/null +++ b/google/cloud/aiplatform_v1/services/tensorboard_service/transports/grpc.py @@ -0,0 +1,1111 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.aiplatform_v1.types import tensorboard +from google.cloud.aiplatform_v1.types import tensorboard_experiment +from google.cloud.aiplatform_v1.types import ( + tensorboard_experiment as gca_tensorboard_experiment, +) +from google.cloud.aiplatform_v1.types import tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_run as gca_tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_service +from google.cloud.aiplatform_v1.types import tensorboard_time_series +from google.cloud.aiplatform_v1.types import ( + tensorboard_time_series as gca_tensorboard_time_series, +) +from google.longrunning import operations_pb2 # type: ignore +from .base import TensorboardServiceTransport, DEFAULT_CLIENT_INFO + + +class TensorboardServiceGrpcTransport(TensorboardServiceTransport): + """gRPC backend transport for TensorboardService. + + TensorboardService + + 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 = "aiplatform.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Sequence[str] = None, + channel: grpc.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel( + cls, + host: str = "aiplatform.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: str = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Sanity check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) + + # Return the client from cache. + return self._operations_client + + @property + def create_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardRequest], operations_pb2.Operation + ]: + r"""Return a callable for the create tensorboard method over gRPC. + + Creates a Tensorboard. + + Returns: + Callable[[~.CreateTensorboardRequest], + ~.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_tensorboard" not in self._stubs: + self._stubs["create_tensorboard"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/CreateTensorboard", + request_serializer=tensorboard_service.CreateTensorboardRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_tensorboard"] + + @property + def get_tensorboard( + self, + ) -> Callable[[tensorboard_service.GetTensorboardRequest], tensorboard.Tensorboard]: + r"""Return a callable for the get tensorboard method over gRPC. + + Gets a Tensorboard. + + Returns: + Callable[[~.GetTensorboardRequest], + ~.Tensorboard]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard" not in self._stubs: + self._stubs["get_tensorboard"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/GetTensorboard", + request_serializer=tensorboard_service.GetTensorboardRequest.serialize, + response_deserializer=tensorboard.Tensorboard.deserialize, + ) + return self._stubs["get_tensorboard"] + + @property + def update_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardRequest], operations_pb2.Operation + ]: + r"""Return a callable for the update tensorboard method over gRPC. + + Updates a Tensorboard. + + Returns: + Callable[[~.UpdateTensorboardRequest], + ~.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_tensorboard" not in self._stubs: + self._stubs["update_tensorboard"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/UpdateTensorboard", + request_serializer=tensorboard_service.UpdateTensorboardRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_tensorboard"] + + @property + def list_tensorboards( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardsRequest], + tensorboard_service.ListTensorboardsResponse, + ]: + r"""Return a callable for the list tensorboards method over gRPC. + + Lists Tensorboards in a Location. + + Returns: + Callable[[~.ListTensorboardsRequest], + ~.ListTensorboardsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboards" not in self._stubs: + self._stubs["list_tensorboards"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ListTensorboards", + request_serializer=tensorboard_service.ListTensorboardsRequest.serialize, + response_deserializer=tensorboard_service.ListTensorboardsResponse.deserialize, + ) + return self._stubs["list_tensorboards"] + + @property + def delete_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardRequest], operations_pb2.Operation + ]: + r"""Return a callable for the delete tensorboard method over gRPC. + + Deletes a Tensorboard. + + Returns: + Callable[[~.DeleteTensorboardRequest], + ~.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_tensorboard" not in self._stubs: + self._stubs["delete_tensorboard"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/DeleteTensorboard", + request_serializer=tensorboard_service.DeleteTensorboardRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_tensorboard"] + + @property + def create_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardExperimentRequest], + gca_tensorboard_experiment.TensorboardExperiment, + ]: + r"""Return a callable for the create tensorboard experiment method over gRPC. + + Creates a TensorboardExperiment. + + Returns: + Callable[[~.CreateTensorboardExperimentRequest], + ~.TensorboardExperiment]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_experiment" not in self._stubs: + self._stubs[ + "create_tensorboard_experiment" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/CreateTensorboardExperiment", + request_serializer=tensorboard_service.CreateTensorboardExperimentRequest.serialize, + response_deserializer=gca_tensorboard_experiment.TensorboardExperiment.deserialize, + ) + return self._stubs["create_tensorboard_experiment"] + + @property + def get_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardExperimentRequest], + tensorboard_experiment.TensorboardExperiment, + ]: + r"""Return a callable for the get tensorboard experiment method over gRPC. + + Gets a TensorboardExperiment. + + Returns: + Callable[[~.GetTensorboardExperimentRequest], + ~.TensorboardExperiment]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_experiment" not in self._stubs: + self._stubs["get_tensorboard_experiment"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/GetTensorboardExperiment", + request_serializer=tensorboard_service.GetTensorboardExperimentRequest.serialize, + response_deserializer=tensorboard_experiment.TensorboardExperiment.deserialize, + ) + return self._stubs["get_tensorboard_experiment"] + + @property + def update_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardExperimentRequest], + gca_tensorboard_experiment.TensorboardExperiment, + ]: + r"""Return a callable for the update tensorboard experiment method over gRPC. + + Updates a TensorboardExperiment. + + Returns: + Callable[[~.UpdateTensorboardExperimentRequest], + ~.TensorboardExperiment]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_experiment" not in self._stubs: + self._stubs[ + "update_tensorboard_experiment" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/UpdateTensorboardExperiment", + request_serializer=tensorboard_service.UpdateTensorboardExperimentRequest.serialize, + response_deserializer=gca_tensorboard_experiment.TensorboardExperiment.deserialize, + ) + return self._stubs["update_tensorboard_experiment"] + + @property + def list_tensorboard_experiments( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardExperimentsRequest], + tensorboard_service.ListTensorboardExperimentsResponse, + ]: + r"""Return a callable for the list tensorboard experiments method over gRPC. + + Lists TensorboardExperiments in a Location. + + Returns: + Callable[[~.ListTensorboardExperimentsRequest], + ~.ListTensorboardExperimentsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_experiments" not in self._stubs: + self._stubs["list_tensorboard_experiments"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ListTensorboardExperiments", + request_serializer=tensorboard_service.ListTensorboardExperimentsRequest.serialize, + response_deserializer=tensorboard_service.ListTensorboardExperimentsResponse.deserialize, + ) + return self._stubs["list_tensorboard_experiments"] + + @property + def delete_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardExperimentRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the delete tensorboard experiment method over gRPC. + + Deletes a TensorboardExperiment. + + Returns: + Callable[[~.DeleteTensorboardExperimentRequest], + ~.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_tensorboard_experiment" not in self._stubs: + self._stubs[ + "delete_tensorboard_experiment" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/DeleteTensorboardExperiment", + request_serializer=tensorboard_service.DeleteTensorboardExperimentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_tensorboard_experiment"] + + @property + def create_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardRunRequest], + gca_tensorboard_run.TensorboardRun, + ]: + r"""Return a callable for the create tensorboard run method over gRPC. + + Creates a TensorboardRun. + + Returns: + Callable[[~.CreateTensorboardRunRequest], + ~.TensorboardRun]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_run" not in self._stubs: + self._stubs["create_tensorboard_run"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/CreateTensorboardRun", + request_serializer=tensorboard_service.CreateTensorboardRunRequest.serialize, + response_deserializer=gca_tensorboard_run.TensorboardRun.deserialize, + ) + return self._stubs["create_tensorboard_run"] + + @property + def batch_create_tensorboard_runs( + self, + ) -> Callable[ + [tensorboard_service.BatchCreateTensorboardRunsRequest], + tensorboard_service.BatchCreateTensorboardRunsResponse, + ]: + r"""Return a callable for the batch create tensorboard runs method over gRPC. + + Batch create TensorboardRuns. + + Returns: + Callable[[~.BatchCreateTensorboardRunsRequest], + ~.BatchCreateTensorboardRunsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_create_tensorboard_runs" not in self._stubs: + self._stubs[ + "batch_create_tensorboard_runs" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/BatchCreateTensorboardRuns", + request_serializer=tensorboard_service.BatchCreateTensorboardRunsRequest.serialize, + response_deserializer=tensorboard_service.BatchCreateTensorboardRunsResponse.deserialize, + ) + return self._stubs["batch_create_tensorboard_runs"] + + @property + def get_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardRunRequest], tensorboard_run.TensorboardRun + ]: + r"""Return a callable for the get tensorboard run method over gRPC. + + Gets a TensorboardRun. + + Returns: + Callable[[~.GetTensorboardRunRequest], + ~.TensorboardRun]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_run" not in self._stubs: + self._stubs["get_tensorboard_run"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/GetTensorboardRun", + request_serializer=tensorboard_service.GetTensorboardRunRequest.serialize, + response_deserializer=tensorboard_run.TensorboardRun.deserialize, + ) + return self._stubs["get_tensorboard_run"] + + @property + def update_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardRunRequest], + gca_tensorboard_run.TensorboardRun, + ]: + r"""Return a callable for the update tensorboard run method over gRPC. + + Updates a TensorboardRun. + + Returns: + Callable[[~.UpdateTensorboardRunRequest], + ~.TensorboardRun]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_run" not in self._stubs: + self._stubs["update_tensorboard_run"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/UpdateTensorboardRun", + request_serializer=tensorboard_service.UpdateTensorboardRunRequest.serialize, + response_deserializer=gca_tensorboard_run.TensorboardRun.deserialize, + ) + return self._stubs["update_tensorboard_run"] + + @property + def list_tensorboard_runs( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardRunsRequest], + tensorboard_service.ListTensorboardRunsResponse, + ]: + r"""Return a callable for the list tensorboard runs method over gRPC. + + Lists TensorboardRuns in a Location. + + Returns: + Callable[[~.ListTensorboardRunsRequest], + ~.ListTensorboardRunsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_runs" not in self._stubs: + self._stubs["list_tensorboard_runs"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ListTensorboardRuns", + request_serializer=tensorboard_service.ListTensorboardRunsRequest.serialize, + response_deserializer=tensorboard_service.ListTensorboardRunsResponse.deserialize, + ) + return self._stubs["list_tensorboard_runs"] + + @property + def delete_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardRunRequest], operations_pb2.Operation + ]: + r"""Return a callable for the delete tensorboard run method over gRPC. + + Deletes a TensorboardRun. + + Returns: + Callable[[~.DeleteTensorboardRunRequest], + ~.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_tensorboard_run" not in self._stubs: + self._stubs["delete_tensorboard_run"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/DeleteTensorboardRun", + request_serializer=tensorboard_service.DeleteTensorboardRunRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_tensorboard_run"] + + @property + def batch_create_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.BatchCreateTensorboardTimeSeriesRequest], + tensorboard_service.BatchCreateTensorboardTimeSeriesResponse, + ]: + r"""Return a callable for the batch create tensorboard time + series method over gRPC. + + Batch create TensorboardTimeSeries that belong to a + TensorboardExperiment. + + Returns: + Callable[[~.BatchCreateTensorboardTimeSeriesRequest], + ~.BatchCreateTensorboardTimeSeriesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_create_tensorboard_time_series" not in self._stubs: + self._stubs[ + "batch_create_tensorboard_time_series" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/BatchCreateTensorboardTimeSeries", + request_serializer=tensorboard_service.BatchCreateTensorboardTimeSeriesRequest.serialize, + response_deserializer=tensorboard_service.BatchCreateTensorboardTimeSeriesResponse.deserialize, + ) + return self._stubs["batch_create_tensorboard_time_series"] + + @property + def create_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardTimeSeriesRequest], + gca_tensorboard_time_series.TensorboardTimeSeries, + ]: + r"""Return a callable for the create tensorboard time series method over gRPC. + + Creates a TensorboardTimeSeries. + + Returns: + Callable[[~.CreateTensorboardTimeSeriesRequest], + ~.TensorboardTimeSeries]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series" not in self._stubs: + self._stubs[ + "create_tensorboard_time_series" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/CreateTensorboardTimeSeries", + request_serializer=tensorboard_service.CreateTensorboardTimeSeriesRequest.serialize, + response_deserializer=gca_tensorboard_time_series.TensorboardTimeSeries.deserialize, + ) + return self._stubs["create_tensorboard_time_series"] + + @property + def get_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardTimeSeriesRequest], + tensorboard_time_series.TensorboardTimeSeries, + ]: + r"""Return a callable for the get tensorboard time series method over gRPC. + + Gets a TensorboardTimeSeries. + + Returns: + Callable[[~.GetTensorboardTimeSeriesRequest], + ~.TensorboardTimeSeries]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series" not in self._stubs: + self._stubs["get_tensorboard_time_series"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/GetTensorboardTimeSeries", + request_serializer=tensorboard_service.GetTensorboardTimeSeriesRequest.serialize, + response_deserializer=tensorboard_time_series.TensorboardTimeSeries.deserialize, + ) + return self._stubs["get_tensorboard_time_series"] + + @property + def update_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardTimeSeriesRequest], + gca_tensorboard_time_series.TensorboardTimeSeries, + ]: + r"""Return a callable for the update tensorboard time series method over gRPC. + + Updates a TensorboardTimeSeries. + + Returns: + Callable[[~.UpdateTensorboardTimeSeriesRequest], + ~.TensorboardTimeSeries]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series" not in self._stubs: + self._stubs[ + "update_tensorboard_time_series" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/UpdateTensorboardTimeSeries", + request_serializer=tensorboard_service.UpdateTensorboardTimeSeriesRequest.serialize, + response_deserializer=gca_tensorboard_time_series.TensorboardTimeSeries.deserialize, + ) + return self._stubs["update_tensorboard_time_series"] + + @property + def list_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardTimeSeriesRequest], + tensorboard_service.ListTensorboardTimeSeriesResponse, + ]: + r"""Return a callable for the list tensorboard time series method over gRPC. + + Lists TensorboardTimeSeries in a Location. + + Returns: + Callable[[~.ListTensorboardTimeSeriesRequest], + ~.ListTensorboardTimeSeriesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series" not in self._stubs: + self._stubs["list_tensorboard_time_series"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ListTensorboardTimeSeries", + request_serializer=tensorboard_service.ListTensorboardTimeSeriesRequest.serialize, + response_deserializer=tensorboard_service.ListTensorboardTimeSeriesResponse.deserialize, + ) + return self._stubs["list_tensorboard_time_series"] + + @property + def delete_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardTimeSeriesRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the delete tensorboard time series method over gRPC. + + Deletes a TensorboardTimeSeries. + + Returns: + Callable[[~.DeleteTensorboardTimeSeriesRequest], + ~.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_tensorboard_time_series" not in self._stubs: + self._stubs[ + "delete_tensorboard_time_series" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/DeleteTensorboardTimeSeries", + request_serializer=tensorboard_service.DeleteTensorboardTimeSeriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_tensorboard_time_series"] + + @property + def batch_read_tensorboard_time_series_data( + self, + ) -> Callable[ + [tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest], + tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse, + ]: + r"""Return a callable for the batch read tensorboard time + series data method over gRPC. + + Reads multiple TensorboardTimeSeries' data. The data + point number limit is 1000 for scalars, 100 for tensors + and blob references. If the number of data points stored + is less than the limit, all data will be returned. + Otherwise, that limit number of data points will be + randomly selected from this time series and returned. + + Returns: + Callable[[~.BatchReadTensorboardTimeSeriesDataRequest], + ~.BatchReadTensorboardTimeSeriesDataResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_read_tensorboard_time_series_data" not in self._stubs: + self._stubs[ + "batch_read_tensorboard_time_series_data" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/BatchReadTensorboardTimeSeriesData", + request_serializer=tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest.serialize, + response_deserializer=tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse.deserialize, + ) + return self._stubs["batch_read_tensorboard_time_series_data"] + + @property + def read_tensorboard_time_series_data( + self, + ) -> Callable[ + [tensorboard_service.ReadTensorboardTimeSeriesDataRequest], + tensorboard_service.ReadTensorboardTimeSeriesDataResponse, + ]: + r"""Return a callable for the read tensorboard time series + data method over gRPC. + + Reads a TensorboardTimeSeries' data. By default, if the number + of data points stored is less than 1000, all data will be + returned. Otherwise, 1000 data points will be randomly selected + from this time series and returned. This value can be changed by + changing max_data_points, which can't be greater than 10k. + + Returns: + Callable[[~.ReadTensorboardTimeSeriesDataRequest], + ~.ReadTensorboardTimeSeriesDataResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "read_tensorboard_time_series_data" not in self._stubs: + self._stubs[ + "read_tensorboard_time_series_data" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ReadTensorboardTimeSeriesData", + request_serializer=tensorboard_service.ReadTensorboardTimeSeriesDataRequest.serialize, + response_deserializer=tensorboard_service.ReadTensorboardTimeSeriesDataResponse.deserialize, + ) + return self._stubs["read_tensorboard_time_series_data"] + + @property + def read_tensorboard_blob_data( + self, + ) -> Callable[ + [tensorboard_service.ReadTensorboardBlobDataRequest], + tensorboard_service.ReadTensorboardBlobDataResponse, + ]: + r"""Return a callable for the read tensorboard blob data method over gRPC. + + Gets bytes of TensorboardBlobs. + This is to allow reading blob data stored in consumer + project's Cloud Storage bucket without users having to + obtain Cloud Storage access permission. + + Returns: + Callable[[~.ReadTensorboardBlobDataRequest], + ~.ReadTensorboardBlobDataResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "read_tensorboard_blob_data" not in self._stubs: + self._stubs["read_tensorboard_blob_data"] = self.grpc_channel.unary_stream( + "/google.cloud.aiplatform.v1.TensorboardService/ReadTensorboardBlobData", + request_serializer=tensorboard_service.ReadTensorboardBlobDataRequest.serialize, + response_deserializer=tensorboard_service.ReadTensorboardBlobDataResponse.deserialize, + ) + return self._stubs["read_tensorboard_blob_data"] + + @property + def write_tensorboard_experiment_data( + self, + ) -> Callable[ + [tensorboard_service.WriteTensorboardExperimentDataRequest], + tensorboard_service.WriteTensorboardExperimentDataResponse, + ]: + r"""Return a callable for the write tensorboard experiment + data method over gRPC. + + Write time series data points of multiple + TensorboardTimeSeries in multiple TensorboardRun's. If + any data fail to be ingested, an error will be returned. + + Returns: + Callable[[~.WriteTensorboardExperimentDataRequest], + ~.WriteTensorboardExperimentDataResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "write_tensorboard_experiment_data" not in self._stubs: + self._stubs[ + "write_tensorboard_experiment_data" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/WriteTensorboardExperimentData", + request_serializer=tensorboard_service.WriteTensorboardExperimentDataRequest.serialize, + response_deserializer=tensorboard_service.WriteTensorboardExperimentDataResponse.deserialize, + ) + return self._stubs["write_tensorboard_experiment_data"] + + @property + def write_tensorboard_run_data( + self, + ) -> Callable[ + [tensorboard_service.WriteTensorboardRunDataRequest], + tensorboard_service.WriteTensorboardRunDataResponse, + ]: + r"""Return a callable for the write tensorboard run data method over gRPC. + + Write time series data points into multiple + TensorboardTimeSeries under a TensorboardRun. If any + data fail to be ingested, an error will be returned. + + Returns: + Callable[[~.WriteTensorboardRunDataRequest], + ~.WriteTensorboardRunDataResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "write_tensorboard_run_data" not in self._stubs: + self._stubs["write_tensorboard_run_data"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/WriteTensorboardRunData", + request_serializer=tensorboard_service.WriteTensorboardRunDataRequest.serialize, + response_deserializer=tensorboard_service.WriteTensorboardRunDataResponse.deserialize, + ) + return self._stubs["write_tensorboard_run_data"] + + @property + def export_tensorboard_time_series_data( + self, + ) -> Callable[ + [tensorboard_service.ExportTensorboardTimeSeriesDataRequest], + tensorboard_service.ExportTensorboardTimeSeriesDataResponse, + ]: + r"""Return a callable for the export tensorboard time series + data method over gRPC. + + Exports a TensorboardTimeSeries' data. Data is + returned in paginated responses. + + Returns: + Callable[[~.ExportTensorboardTimeSeriesDataRequest], + ~.ExportTensorboardTimeSeriesDataResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series_data" not in self._stubs: + self._stubs[ + "export_tensorboard_time_series_data" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ExportTensorboardTimeSeriesData", + request_serializer=tensorboard_service.ExportTensorboardTimeSeriesDataRequest.serialize, + response_deserializer=tensorboard_service.ExportTensorboardTimeSeriesDataResponse.deserialize, + ) + return self._stubs["export_tensorboard_time_series_data"] + + def close(self): + self.grpc_channel.close() + + +__all__ = ("TensorboardServiceGrpcTransport",) diff --git a/google/cloud/aiplatform_v1/services/tensorboard_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/tensorboard_service/transports/grpc_asyncio.py new file mode 100644 index 0000000000..68b73e9218 --- /dev/null +++ b/google/cloud/aiplatform_v1/services/tensorboard_service/transports/grpc_asyncio.py @@ -0,0 +1,1122 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.aiplatform_v1.types import tensorboard +from google.cloud.aiplatform_v1.types import tensorboard_experiment +from google.cloud.aiplatform_v1.types import ( + tensorboard_experiment as gca_tensorboard_experiment, +) +from google.cloud.aiplatform_v1.types import tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_run as gca_tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_service +from google.cloud.aiplatform_v1.types import tensorboard_time_series +from google.cloud.aiplatform_v1.types import ( + tensorboard_time_series as gca_tensorboard_time_series, +) +from google.longrunning import operations_pb2 # type: ignore +from .base import TensorboardServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import TensorboardServiceGrpcTransport + + +class TensorboardServiceGrpcAsyncIOTransport(TensorboardServiceTransport): + """gRPC AsyncIO backend transport for TensorboardService. + + TensorboardService + + 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 = "aiplatform.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "aiplatform.googleapis.com", + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Sanity check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the create tensorboard method over gRPC. + + Creates a Tensorboard. + + Returns: + Callable[[~.CreateTensorboardRequest], + 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_tensorboard" not in self._stubs: + self._stubs["create_tensorboard"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/CreateTensorboard", + request_serializer=tensorboard_service.CreateTensorboardRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_tensorboard"] + + @property + def get_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardRequest], Awaitable[tensorboard.Tensorboard] + ]: + r"""Return a callable for the get tensorboard method over gRPC. + + Gets a Tensorboard. + + Returns: + Callable[[~.GetTensorboardRequest], + Awaitable[~.Tensorboard]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard" not in self._stubs: + self._stubs["get_tensorboard"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/GetTensorboard", + request_serializer=tensorboard_service.GetTensorboardRequest.serialize, + response_deserializer=tensorboard.Tensorboard.deserialize, + ) + return self._stubs["get_tensorboard"] + + @property + def update_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the update tensorboard method over gRPC. + + Updates a Tensorboard. + + Returns: + Callable[[~.UpdateTensorboardRequest], + 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_tensorboard" not in self._stubs: + self._stubs["update_tensorboard"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/UpdateTensorboard", + request_serializer=tensorboard_service.UpdateTensorboardRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["update_tensorboard"] + + @property + def list_tensorboards( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardsRequest], + Awaitable[tensorboard_service.ListTensorboardsResponse], + ]: + r"""Return a callable for the list tensorboards method over gRPC. + + Lists Tensorboards in a Location. + + Returns: + Callable[[~.ListTensorboardsRequest], + Awaitable[~.ListTensorboardsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboards" not in self._stubs: + self._stubs["list_tensorboards"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ListTensorboards", + request_serializer=tensorboard_service.ListTensorboardsRequest.serialize, + response_deserializer=tensorboard_service.ListTensorboardsResponse.deserialize, + ) + return self._stubs["list_tensorboards"] + + @property + def delete_tensorboard( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete tensorboard method over gRPC. + + Deletes a Tensorboard. + + Returns: + Callable[[~.DeleteTensorboardRequest], + 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_tensorboard" not in self._stubs: + self._stubs["delete_tensorboard"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/DeleteTensorboard", + request_serializer=tensorboard_service.DeleteTensorboardRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_tensorboard"] + + @property + def create_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardExperimentRequest], + Awaitable[gca_tensorboard_experiment.TensorboardExperiment], + ]: + r"""Return a callable for the create tensorboard experiment method over gRPC. + + Creates a TensorboardExperiment. + + Returns: + Callable[[~.CreateTensorboardExperimentRequest], + Awaitable[~.TensorboardExperiment]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_experiment" not in self._stubs: + self._stubs[ + "create_tensorboard_experiment" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/CreateTensorboardExperiment", + request_serializer=tensorboard_service.CreateTensorboardExperimentRequest.serialize, + response_deserializer=gca_tensorboard_experiment.TensorboardExperiment.deserialize, + ) + return self._stubs["create_tensorboard_experiment"] + + @property + def get_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardExperimentRequest], + Awaitable[tensorboard_experiment.TensorboardExperiment], + ]: + r"""Return a callable for the get tensorboard experiment method over gRPC. + + Gets a TensorboardExperiment. + + Returns: + Callable[[~.GetTensorboardExperimentRequest], + Awaitable[~.TensorboardExperiment]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_experiment" not in self._stubs: + self._stubs["get_tensorboard_experiment"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/GetTensorboardExperiment", + request_serializer=tensorboard_service.GetTensorboardExperimentRequest.serialize, + response_deserializer=tensorboard_experiment.TensorboardExperiment.deserialize, + ) + return self._stubs["get_tensorboard_experiment"] + + @property + def update_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardExperimentRequest], + Awaitable[gca_tensorboard_experiment.TensorboardExperiment], + ]: + r"""Return a callable for the update tensorboard experiment method over gRPC. + + Updates a TensorboardExperiment. + + Returns: + Callable[[~.UpdateTensorboardExperimentRequest], + Awaitable[~.TensorboardExperiment]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_experiment" not in self._stubs: + self._stubs[ + "update_tensorboard_experiment" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/UpdateTensorboardExperiment", + request_serializer=tensorboard_service.UpdateTensorboardExperimentRequest.serialize, + response_deserializer=gca_tensorboard_experiment.TensorboardExperiment.deserialize, + ) + return self._stubs["update_tensorboard_experiment"] + + @property + def list_tensorboard_experiments( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardExperimentsRequest], + Awaitable[tensorboard_service.ListTensorboardExperimentsResponse], + ]: + r"""Return a callable for the list tensorboard experiments method over gRPC. + + Lists TensorboardExperiments in a Location. + + Returns: + Callable[[~.ListTensorboardExperimentsRequest], + Awaitable[~.ListTensorboardExperimentsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_experiments" not in self._stubs: + self._stubs["list_tensorboard_experiments"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ListTensorboardExperiments", + request_serializer=tensorboard_service.ListTensorboardExperimentsRequest.serialize, + response_deserializer=tensorboard_service.ListTensorboardExperimentsResponse.deserialize, + ) + return self._stubs["list_tensorboard_experiments"] + + @property + def delete_tensorboard_experiment( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardExperimentRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete tensorboard experiment method over gRPC. + + Deletes a TensorboardExperiment. + + Returns: + Callable[[~.DeleteTensorboardExperimentRequest], + 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_tensorboard_experiment" not in self._stubs: + self._stubs[ + "delete_tensorboard_experiment" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/DeleteTensorboardExperiment", + request_serializer=tensorboard_service.DeleteTensorboardExperimentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_tensorboard_experiment"] + + @property + def create_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardRunRequest], + Awaitable[gca_tensorboard_run.TensorboardRun], + ]: + r"""Return a callable for the create tensorboard run method over gRPC. + + Creates a TensorboardRun. + + Returns: + Callable[[~.CreateTensorboardRunRequest], + Awaitable[~.TensorboardRun]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_run" not in self._stubs: + self._stubs["create_tensorboard_run"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/CreateTensorboardRun", + request_serializer=tensorboard_service.CreateTensorboardRunRequest.serialize, + response_deserializer=gca_tensorboard_run.TensorboardRun.deserialize, + ) + return self._stubs["create_tensorboard_run"] + + @property + def batch_create_tensorboard_runs( + self, + ) -> Callable[ + [tensorboard_service.BatchCreateTensorboardRunsRequest], + Awaitable[tensorboard_service.BatchCreateTensorboardRunsResponse], + ]: + r"""Return a callable for the batch create tensorboard runs method over gRPC. + + Batch create TensorboardRuns. + + Returns: + Callable[[~.BatchCreateTensorboardRunsRequest], + Awaitable[~.BatchCreateTensorboardRunsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_create_tensorboard_runs" not in self._stubs: + self._stubs[ + "batch_create_tensorboard_runs" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/BatchCreateTensorboardRuns", + request_serializer=tensorboard_service.BatchCreateTensorboardRunsRequest.serialize, + response_deserializer=tensorboard_service.BatchCreateTensorboardRunsResponse.deserialize, + ) + return self._stubs["batch_create_tensorboard_runs"] + + @property + def get_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardRunRequest], + Awaitable[tensorboard_run.TensorboardRun], + ]: + r"""Return a callable for the get tensorboard run method over gRPC. + + Gets a TensorboardRun. + + Returns: + Callable[[~.GetTensorboardRunRequest], + Awaitable[~.TensorboardRun]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_run" not in self._stubs: + self._stubs["get_tensorboard_run"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/GetTensorboardRun", + request_serializer=tensorboard_service.GetTensorboardRunRequest.serialize, + response_deserializer=tensorboard_run.TensorboardRun.deserialize, + ) + return self._stubs["get_tensorboard_run"] + + @property + def update_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardRunRequest], + Awaitable[gca_tensorboard_run.TensorboardRun], + ]: + r"""Return a callable for the update tensorboard run method over gRPC. + + Updates a TensorboardRun. + + Returns: + Callable[[~.UpdateTensorboardRunRequest], + Awaitable[~.TensorboardRun]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_run" not in self._stubs: + self._stubs["update_tensorboard_run"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/UpdateTensorboardRun", + request_serializer=tensorboard_service.UpdateTensorboardRunRequest.serialize, + response_deserializer=gca_tensorboard_run.TensorboardRun.deserialize, + ) + return self._stubs["update_tensorboard_run"] + + @property + def list_tensorboard_runs( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardRunsRequest], + Awaitable[tensorboard_service.ListTensorboardRunsResponse], + ]: + r"""Return a callable for the list tensorboard runs method over gRPC. + + Lists TensorboardRuns in a Location. + + Returns: + Callable[[~.ListTensorboardRunsRequest], + Awaitable[~.ListTensorboardRunsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_runs" not in self._stubs: + self._stubs["list_tensorboard_runs"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ListTensorboardRuns", + request_serializer=tensorboard_service.ListTensorboardRunsRequest.serialize, + response_deserializer=tensorboard_service.ListTensorboardRunsResponse.deserialize, + ) + return self._stubs["list_tensorboard_runs"] + + @property + def delete_tensorboard_run( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardRunRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete tensorboard run method over gRPC. + + Deletes a TensorboardRun. + + Returns: + Callable[[~.DeleteTensorboardRunRequest], + 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_tensorboard_run" not in self._stubs: + self._stubs["delete_tensorboard_run"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/DeleteTensorboardRun", + request_serializer=tensorboard_service.DeleteTensorboardRunRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_tensorboard_run"] + + @property + def batch_create_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.BatchCreateTensorboardTimeSeriesRequest], + Awaitable[tensorboard_service.BatchCreateTensorboardTimeSeriesResponse], + ]: + r"""Return a callable for the batch create tensorboard time + series method over gRPC. + + Batch create TensorboardTimeSeries that belong to a + TensorboardExperiment. + + Returns: + Callable[[~.BatchCreateTensorboardTimeSeriesRequest], + Awaitable[~.BatchCreateTensorboardTimeSeriesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_create_tensorboard_time_series" not in self._stubs: + self._stubs[ + "batch_create_tensorboard_time_series" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/BatchCreateTensorboardTimeSeries", + request_serializer=tensorboard_service.BatchCreateTensorboardTimeSeriesRequest.serialize, + response_deserializer=tensorboard_service.BatchCreateTensorboardTimeSeriesResponse.deserialize, + ) + return self._stubs["batch_create_tensorboard_time_series"] + + @property + def create_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.CreateTensorboardTimeSeriesRequest], + Awaitable[gca_tensorboard_time_series.TensorboardTimeSeries], + ]: + r"""Return a callable for the create tensorboard time series method over gRPC. + + Creates a TensorboardTimeSeries. + + Returns: + Callable[[~.CreateTensorboardTimeSeriesRequest], + Awaitable[~.TensorboardTimeSeries]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series" not in self._stubs: + self._stubs[ + "create_tensorboard_time_series" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/CreateTensorboardTimeSeries", + request_serializer=tensorboard_service.CreateTensorboardTimeSeriesRequest.serialize, + response_deserializer=gca_tensorboard_time_series.TensorboardTimeSeries.deserialize, + ) + return self._stubs["create_tensorboard_time_series"] + + @property + def get_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.GetTensorboardTimeSeriesRequest], + Awaitable[tensorboard_time_series.TensorboardTimeSeries], + ]: + r"""Return a callable for the get tensorboard time series method over gRPC. + + Gets a TensorboardTimeSeries. + + Returns: + Callable[[~.GetTensorboardTimeSeriesRequest], + Awaitable[~.TensorboardTimeSeries]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series" not in self._stubs: + self._stubs["get_tensorboard_time_series"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/GetTensorboardTimeSeries", + request_serializer=tensorboard_service.GetTensorboardTimeSeriesRequest.serialize, + response_deserializer=tensorboard_time_series.TensorboardTimeSeries.deserialize, + ) + return self._stubs["get_tensorboard_time_series"] + + @property + def update_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.UpdateTensorboardTimeSeriesRequest], + Awaitable[gca_tensorboard_time_series.TensorboardTimeSeries], + ]: + r"""Return a callable for the update tensorboard time series method over gRPC. + + Updates a TensorboardTimeSeries. + + Returns: + Callable[[~.UpdateTensorboardTimeSeriesRequest], + Awaitable[~.TensorboardTimeSeries]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series" not in self._stubs: + self._stubs[ + "update_tensorboard_time_series" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/UpdateTensorboardTimeSeries", + request_serializer=tensorboard_service.UpdateTensorboardTimeSeriesRequest.serialize, + response_deserializer=gca_tensorboard_time_series.TensorboardTimeSeries.deserialize, + ) + return self._stubs["update_tensorboard_time_series"] + + @property + def list_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.ListTensorboardTimeSeriesRequest], + Awaitable[tensorboard_service.ListTensorboardTimeSeriesResponse], + ]: + r"""Return a callable for the list tensorboard time series method over gRPC. + + Lists TensorboardTimeSeries in a Location. + + Returns: + Callable[[~.ListTensorboardTimeSeriesRequest], + Awaitable[~.ListTensorboardTimeSeriesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series" not in self._stubs: + self._stubs["list_tensorboard_time_series"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ListTensorboardTimeSeries", + request_serializer=tensorboard_service.ListTensorboardTimeSeriesRequest.serialize, + response_deserializer=tensorboard_service.ListTensorboardTimeSeriesResponse.deserialize, + ) + return self._stubs["list_tensorboard_time_series"] + + @property + def delete_tensorboard_time_series( + self, + ) -> Callable[ + [tensorboard_service.DeleteTensorboardTimeSeriesRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the delete tensorboard time series method over gRPC. + + Deletes a TensorboardTimeSeries. + + Returns: + Callable[[~.DeleteTensorboardTimeSeriesRequest], + 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_tensorboard_time_series" not in self._stubs: + self._stubs[ + "delete_tensorboard_time_series" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/DeleteTensorboardTimeSeries", + request_serializer=tensorboard_service.DeleteTensorboardTimeSeriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["delete_tensorboard_time_series"] + + @property + def batch_read_tensorboard_time_series_data( + self, + ) -> Callable[ + [tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest], + Awaitable[tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse], + ]: + r"""Return a callable for the batch read tensorboard time + series data method over gRPC. + + Reads multiple TensorboardTimeSeries' data. The data + point number limit is 1000 for scalars, 100 for tensors + and blob references. If the number of data points stored + is less than the limit, all data will be returned. + Otherwise, that limit number of data points will be + randomly selected from this time series and returned. + + Returns: + Callable[[~.BatchReadTensorboardTimeSeriesDataRequest], + Awaitable[~.BatchReadTensorboardTimeSeriesDataResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_read_tensorboard_time_series_data" not in self._stubs: + self._stubs[ + "batch_read_tensorboard_time_series_data" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/BatchReadTensorboardTimeSeriesData", + request_serializer=tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest.serialize, + response_deserializer=tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse.deserialize, + ) + return self._stubs["batch_read_tensorboard_time_series_data"] + + @property + def read_tensorboard_time_series_data( + self, + ) -> Callable[ + [tensorboard_service.ReadTensorboardTimeSeriesDataRequest], + Awaitable[tensorboard_service.ReadTensorboardTimeSeriesDataResponse], + ]: + r"""Return a callable for the read tensorboard time series + data method over gRPC. + + Reads a TensorboardTimeSeries' data. By default, if the number + of data points stored is less than 1000, all data will be + returned. Otherwise, 1000 data points will be randomly selected + from this time series and returned. This value can be changed by + changing max_data_points, which can't be greater than 10k. + + Returns: + Callable[[~.ReadTensorboardTimeSeriesDataRequest], + Awaitable[~.ReadTensorboardTimeSeriesDataResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "read_tensorboard_time_series_data" not in self._stubs: + self._stubs[ + "read_tensorboard_time_series_data" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ReadTensorboardTimeSeriesData", + request_serializer=tensorboard_service.ReadTensorboardTimeSeriesDataRequest.serialize, + response_deserializer=tensorboard_service.ReadTensorboardTimeSeriesDataResponse.deserialize, + ) + return self._stubs["read_tensorboard_time_series_data"] + + @property + def read_tensorboard_blob_data( + self, + ) -> Callable[ + [tensorboard_service.ReadTensorboardBlobDataRequest], + Awaitable[tensorboard_service.ReadTensorboardBlobDataResponse], + ]: + r"""Return a callable for the read tensorboard blob data method over gRPC. + + Gets bytes of TensorboardBlobs. + This is to allow reading blob data stored in consumer + project's Cloud Storage bucket without users having to + obtain Cloud Storage access permission. + + Returns: + Callable[[~.ReadTensorboardBlobDataRequest], + Awaitable[~.ReadTensorboardBlobDataResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "read_tensorboard_blob_data" not in self._stubs: + self._stubs["read_tensorboard_blob_data"] = self.grpc_channel.unary_stream( + "/google.cloud.aiplatform.v1.TensorboardService/ReadTensorboardBlobData", + request_serializer=tensorboard_service.ReadTensorboardBlobDataRequest.serialize, + response_deserializer=tensorboard_service.ReadTensorboardBlobDataResponse.deserialize, + ) + return self._stubs["read_tensorboard_blob_data"] + + @property + def write_tensorboard_experiment_data( + self, + ) -> Callable[ + [tensorboard_service.WriteTensorboardExperimentDataRequest], + Awaitable[tensorboard_service.WriteTensorboardExperimentDataResponse], + ]: + r"""Return a callable for the write tensorboard experiment + data method over gRPC. + + Write time series data points of multiple + TensorboardTimeSeries in multiple TensorboardRun's. If + any data fail to be ingested, an error will be returned. + + Returns: + Callable[[~.WriteTensorboardExperimentDataRequest], + Awaitable[~.WriteTensorboardExperimentDataResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "write_tensorboard_experiment_data" not in self._stubs: + self._stubs[ + "write_tensorboard_experiment_data" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/WriteTensorboardExperimentData", + request_serializer=tensorboard_service.WriteTensorboardExperimentDataRequest.serialize, + response_deserializer=tensorboard_service.WriteTensorboardExperimentDataResponse.deserialize, + ) + return self._stubs["write_tensorboard_experiment_data"] + + @property + def write_tensorboard_run_data( + self, + ) -> Callable[ + [tensorboard_service.WriteTensorboardRunDataRequest], + Awaitable[tensorboard_service.WriteTensorboardRunDataResponse], + ]: + r"""Return a callable for the write tensorboard run data method over gRPC. + + Write time series data points into multiple + TensorboardTimeSeries under a TensorboardRun. If any + data fail to be ingested, an error will be returned. + + Returns: + Callable[[~.WriteTensorboardRunDataRequest], + Awaitable[~.WriteTensorboardRunDataResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "write_tensorboard_run_data" not in self._stubs: + self._stubs["write_tensorboard_run_data"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/WriteTensorboardRunData", + request_serializer=tensorboard_service.WriteTensorboardRunDataRequest.serialize, + response_deserializer=tensorboard_service.WriteTensorboardRunDataResponse.deserialize, + ) + return self._stubs["write_tensorboard_run_data"] + + @property + def export_tensorboard_time_series_data( + self, + ) -> Callable[ + [tensorboard_service.ExportTensorboardTimeSeriesDataRequest], + Awaitable[tensorboard_service.ExportTensorboardTimeSeriesDataResponse], + ]: + r"""Return a callable for the export tensorboard time series + data method over gRPC. + + Exports a TensorboardTimeSeries' data. Data is + returned in paginated responses. + + Returns: + Callable[[~.ExportTensorboardTimeSeriesDataRequest], + Awaitable[~.ExportTensorboardTimeSeriesDataResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tensorboard_time_series_data" not in self._stubs: + self._stubs[ + "export_tensorboard_time_series_data" + ] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1.TensorboardService/ExportTensorboardTimeSeriesData", + request_serializer=tensorboard_service.ExportTensorboardTimeSeriesDataRequest.serialize, + response_deserializer=tensorboard_service.ExportTensorboardTimeSeriesDataResponse.deserialize, + ) + return self._stubs["export_tensorboard_time_series_data"] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ("TensorboardServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/aiplatform_v1/services/vizier_service/async_client.py b/google/cloud/aiplatform_v1/services/vizier_service/async_client.py index 42ffa973e0..ced1379087 100644 --- a/google/cloud/aiplatform_v1/services/vizier_service/async_client.py +++ b/google/cloud/aiplatform_v1/services/vizier_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore @@ -41,8 +44,8 @@ class VizierServiceAsyncClient: - """Vertex Vizier API. - Vizier service is a GCP service to solve blackbox optimization + """Vertex AI Vizier API. + Vertex AI Vizier is a service to solve blackbox optimization problems, such as tuning machine learning hyperparameters and searching over deep learning architectures. """ @@ -216,7 +219,9 @@ async def create_study( Returns: google.cloud.aiplatform_v1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -287,7 +292,9 @@ async def get_study( Returns: google.cloud.aiplatform_v1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -505,7 +512,9 @@ async def lookup_study( Returns: google.cloud.aiplatform_v1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -553,7 +562,7 @@ async def suggest_trials( metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: r"""Adds one or more Trials to a Study, with parameter values - suggested by Vertex Vizier. Returns a long-running operation + suggested by Vertex AI Vizier. Returns a long-running operation associated with the generation of Trial suggestions. When this long-running operation succeeds, it will contain a [SuggestTrialsResponse][google.cloud.ml.v1.SuggestTrialsResponse]. diff --git a/google/cloud/aiplatform_v1/services/vizier_service/client.py b/google/cloud/aiplatform_v1/services/vizier_service/client.py index e012d4ea31..66a9e42510 100644 --- a/google/cloud/aiplatform_v1/services/vizier_service/client.py +++ b/google/cloud/aiplatform_v1/services/vizier_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore @@ -76,8 +78,8 @@ def get_transport_class(cls, label: str = None,) -> Type[VizierServiceTransport] class VizierServiceClient(metaclass=VizierServiceClientMeta): - """Vertex Vizier API. - Vizier service is a GCP service to solve blackbox optimization + """Vertex AI Vizier API. + Vertex AI Vizier is a service to solve blackbox optimization problems, such as tuning machine learning hyperparameters and searching over deep learning architectures. """ @@ -322,8 +324,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -428,7 +437,9 @@ def create_study( Returns: google.cloud.aiplatform_v1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -499,7 +510,9 @@ def get_study( Returns: google.cloud.aiplatform_v1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -717,7 +730,9 @@ def lookup_study( Returns: google.cloud.aiplatform_v1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -765,7 +780,7 @@ def suggest_trials( metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: r"""Adds one or more Trials to a Study, with parameter values - suggested by Vertex Vizier. Returns a long-running operation + suggested by Vertex AI Vizier. Returns a long-running operation associated with the generation of Trial suggestions. When this long-running operation succeeds, it will contain a [SuggestTrialsResponse][google.cloud.ml.v1.SuggestTrialsResponse]. diff --git a/google/cloud/aiplatform_v1/services/vizier_service/transports/base.py b/google/cloud/aiplatform_v1/services/vizier_service/transports/base.py index 665279bc02..a31cdaf9ff 100644 --- a/google/cloud/aiplatform_v1/services/vizier_service/transports/base.py +++ b/google/cloud/aiplatform_v1/services/vizier_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1/services/vizier_service/transports/grpc.py b/google/cloud/aiplatform_v1/services/vizier_service/transports/grpc.py index 8d644fec28..9a3aab47d2 100644 --- a/google/cloud/aiplatform_v1/services/vizier_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1/services/vizier_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -36,8 +36,8 @@ class VizierServiceGrpcTransport(VizierServiceTransport): """gRPC backend transport for VizierService. - Vertex Vizier API. - Vizier service is a GCP service to solve blackbox optimization + Vertex AI Vizier API. + Vertex AI Vizier is a service to solve blackbox optimization problems, such as tuning machine learning hyperparameters and searching over deep learning architectures. @@ -388,7 +388,7 @@ def suggest_trials( r"""Return a callable for the suggest trials method over gRPC. Adds one or more Trials to a Study, with parameter values - suggested by Vertex Vizier. Returns a long-running operation + suggested by Vertex AI Vizier. Returns a long-running operation associated with the generation of Trial suggestions. When this long-running operation succeeds, it will contain a [SuggestTrialsResponse][google.cloud.ml.v1.SuggestTrialsResponse]. diff --git a/google/cloud/aiplatform_v1/services/vizier_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1/services/vizier_service/transports/grpc_asyncio.py index 71f0f8b8ff..d9506d8902 100644 --- a/google/cloud/aiplatform_v1/services/vizier_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1/services/vizier_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -37,8 +37,8 @@ class VizierServiceGrpcAsyncIOTransport(VizierServiceTransport): """gRPC AsyncIO backend transport for VizierService. - Vertex Vizier API. - Vizier service is a GCP service to solve blackbox optimization + Vertex AI Vizier API. + Vertex AI Vizier is a service to solve blackbox optimization problems, such as tuning machine learning hyperparameters and searching over deep learning architectures. @@ -397,7 +397,7 @@ def suggest_trials( r"""Return a callable for the suggest trials method over gRPC. Adds one or more Trials to a Study, with parameter values - suggested by Vertex Vizier. Returns a long-running operation + suggested by Vertex AI Vizier. Returns a long-running operation associated with the generation of Trial suggestions. When this long-running operation succeeds, it will contain a [SuggestTrialsResponse][google.cloud.ml.v1.SuggestTrialsResponse]. diff --git a/google/cloud/aiplatform_v1/types/__init__.py b/google/cloud/aiplatform_v1/types/__init__.py index 54fb1c7869..7ba335642c 100644 --- a/google/cloud/aiplatform_v1/types/__init__.py +++ b/google/cloud/aiplatform_v1/types/__init__.py @@ -88,6 +88,7 @@ from .execution import Execution from .explanation import ( Attribution, + BlurBaselineConfig, Explanation, ExplanationMetadataOverride, ExplanationParameters, @@ -173,6 +174,9 @@ GetIndexEndpointRequest, ListIndexEndpointsRequest, ListIndexEndpointsResponse, + MutateDeployedIndexOperationMetadata, + MutateDeployedIndexRequest, + MutateDeployedIndexResponse, UndeployIndexOperationMetadata, UndeployIndexRequest, UndeployIndexResponse, @@ -398,11 +402,68 @@ StudySpec, Trial, ) +from .tensorboard import Tensorboard +from .tensorboard_data import ( + Scalar, + TensorboardBlob, + TensorboardBlobSequence, + TensorboardTensor, + TimeSeriesData, + TimeSeriesDataPoint, +) +from .tensorboard_experiment import TensorboardExperiment +from .tensorboard_run import TensorboardRun +from .tensorboard_service import ( + BatchCreateTensorboardRunsRequest, + BatchCreateTensorboardRunsResponse, + BatchCreateTensorboardTimeSeriesRequest, + BatchCreateTensorboardTimeSeriesResponse, + BatchReadTensorboardTimeSeriesDataRequest, + BatchReadTensorboardTimeSeriesDataResponse, + CreateTensorboardExperimentRequest, + CreateTensorboardOperationMetadata, + CreateTensorboardRequest, + CreateTensorboardRunRequest, + CreateTensorboardTimeSeriesRequest, + DeleteTensorboardExperimentRequest, + DeleteTensorboardRequest, + DeleteTensorboardRunRequest, + DeleteTensorboardTimeSeriesRequest, + ExportTensorboardTimeSeriesDataRequest, + ExportTensorboardTimeSeriesDataResponse, + GetTensorboardExperimentRequest, + GetTensorboardRequest, + GetTensorboardRunRequest, + GetTensorboardTimeSeriesRequest, + ListTensorboardExperimentsRequest, + ListTensorboardExperimentsResponse, + ListTensorboardRunsRequest, + ListTensorboardRunsResponse, + ListTensorboardsRequest, + ListTensorboardsResponse, + ListTensorboardTimeSeriesRequest, + ListTensorboardTimeSeriesResponse, + ReadTensorboardBlobDataRequest, + ReadTensorboardBlobDataResponse, + ReadTensorboardTimeSeriesDataRequest, + ReadTensorboardTimeSeriesDataResponse, + UpdateTensorboardExperimentRequest, + UpdateTensorboardOperationMetadata, + UpdateTensorboardRequest, + UpdateTensorboardRunRequest, + UpdateTensorboardTimeSeriesRequest, + WriteTensorboardExperimentDataRequest, + WriteTensorboardExperimentDataResponse, + WriteTensorboardRunDataRequest, + WriteTensorboardRunDataResponse, +) +from .tensorboard_time_series import TensorboardTimeSeries from .training_pipeline import ( FilterSplit, FractionSplit, InputDataConfig, PredefinedSplit, + StratifiedSplit, TimestampSplit, TrainingPipeline, ) @@ -412,6 +473,7 @@ Int64Array, StringArray, ) +from .unmanaged_container_model import UnmanagedContainerModel from .user_action_reference import UserActionReference from .value import Value from .vizier_service import ( @@ -503,6 +565,7 @@ "Event", "Execution", "Attribution", + "BlurBaselineConfig", "Explanation", "ExplanationMetadataOverride", "ExplanationParameters", @@ -578,6 +641,9 @@ "GetIndexEndpointRequest", "ListIndexEndpointsRequest", "ListIndexEndpointsResponse", + "MutateDeployedIndexOperationMetadata", + "MutateDeployedIndexRequest", + "MutateDeployedIndexResponse", "UndeployIndexOperationMetadata", "UndeployIndexRequest", "UndeployIndexResponse", @@ -772,16 +838,70 @@ "Study", "StudySpec", "Trial", + "Tensorboard", + "Scalar", + "TensorboardBlob", + "TensorboardBlobSequence", + "TensorboardTensor", + "TimeSeriesData", + "TimeSeriesDataPoint", + "TensorboardExperiment", + "TensorboardRun", + "BatchCreateTensorboardRunsRequest", + "BatchCreateTensorboardRunsResponse", + "BatchCreateTensorboardTimeSeriesRequest", + "BatchCreateTensorboardTimeSeriesResponse", + "BatchReadTensorboardTimeSeriesDataRequest", + "BatchReadTensorboardTimeSeriesDataResponse", + "CreateTensorboardExperimentRequest", + "CreateTensorboardOperationMetadata", + "CreateTensorboardRequest", + "CreateTensorboardRunRequest", + "CreateTensorboardTimeSeriesRequest", + "DeleteTensorboardExperimentRequest", + "DeleteTensorboardRequest", + "DeleteTensorboardRunRequest", + "DeleteTensorboardTimeSeriesRequest", + "ExportTensorboardTimeSeriesDataRequest", + "ExportTensorboardTimeSeriesDataResponse", + "GetTensorboardExperimentRequest", + "GetTensorboardRequest", + "GetTensorboardRunRequest", + "GetTensorboardTimeSeriesRequest", + "ListTensorboardExperimentsRequest", + "ListTensorboardExperimentsResponse", + "ListTensorboardRunsRequest", + "ListTensorboardRunsResponse", + "ListTensorboardsRequest", + "ListTensorboardsResponse", + "ListTensorboardTimeSeriesRequest", + "ListTensorboardTimeSeriesResponse", + "ReadTensorboardBlobDataRequest", + "ReadTensorboardBlobDataResponse", + "ReadTensorboardTimeSeriesDataRequest", + "ReadTensorboardTimeSeriesDataResponse", + "UpdateTensorboardExperimentRequest", + "UpdateTensorboardOperationMetadata", + "UpdateTensorboardRequest", + "UpdateTensorboardRunRequest", + "UpdateTensorboardTimeSeriesRequest", + "WriteTensorboardExperimentDataRequest", + "WriteTensorboardExperimentDataResponse", + "WriteTensorboardRunDataRequest", + "WriteTensorboardRunDataResponse", + "TensorboardTimeSeries", "FilterSplit", "FractionSplit", "InputDataConfig", "PredefinedSplit", + "StratifiedSplit", "TimestampSplit", "TrainingPipeline", "BoolArray", "DoubleArray", "Int64Array", "StringArray", + "UnmanagedContainerModel", "UserActionReference", "Value", "AddTrialMeasurementRequest", diff --git a/google/cloud/aiplatform_v1/types/artifact.py b/google/cloud/aiplatform_v1/types/artifact.py index aed8db7885..6042601790 100644 --- a/google/cloud/aiplatform_v1/types/artifact.py +++ b/google/cloud/aiplatform_v1/types/artifact.py @@ -62,9 +62,9 @@ class Artifact(proto.Message): The state of this Artifact. This is a property of the Artifact, and does not imply or capture any ongoing process. This property is - managed by clients (such as Vertex Pipelines), - and the system does not prescribe or check the - validity of state transitions. + managed by clients (such as Vertex AI + Pipelines), and the system does not prescribe or + check the validity of state transitions. schema_title (str): The title of the schema describing the metadata. diff --git a/google/cloud/aiplatform_v1/types/batch_prediction_job.py b/google/cloud/aiplatform_v1/types/batch_prediction_job.py index a62c55e739..350951bc17 100644 --- a/google/cloud/aiplatform_v1/types/batch_prediction_job.py +++ b/google/cloud/aiplatform_v1/types/batch_prediction_job.py @@ -24,6 +24,9 @@ from google.cloud.aiplatform_v1.types import ( manual_batch_tuning_parameters as gca_manual_batch_tuning_parameters, ) +from google.cloud.aiplatform_v1.types import ( + unmanaged_container_model as gca_unmanaged_container_model, +) from google.protobuf import struct_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore @@ -51,11 +54,16 @@ class BatchPredictionJob(proto.Message): Required. The user-defined name of this BatchPredictionJob. model (str): - Required. The name of the Model that produces - the predictions via this job, must share the - same ancestor Location. Starting this job has no - impact on any existing deployments of the Model - and their resources. + The name of the Model resoure that produces the predictions + via this job, must share the same ancestor Location. + Starting this job has no impact on any existing deployments + of the Model and their resources. Exactly one of model and + unmanaged_container_model must be set. + unmanaged_container_model (google.cloud.aiplatform_v1.types.UnmanagedContainerModel): + Contains model information necessary to perform batch + prediction without requiring uploading to model registry. + Exactly one of model and unmanaged_container_model must be + set. input_config (google.cloud.aiplatform_v1.types.BatchPredictionJob.InputConfig): Required. Input configuration of the instances on which predictions are performed. The schema of any single instance @@ -204,6 +212,7 @@ class InputConfig(proto.Message): gcs_source (google.cloud.aiplatform_v1.types.GcsSource): The Cloud Storage location for the input instances. + This field is a member of `oneof`_ ``source``. bigquery_source (google.cloud.aiplatform_v1.types.BigQuerySource): The BigQuery location of the input table. @@ -212,6 +221,7 @@ class InputConfig(proto.Message): if one is provided. The table may contain additional columns that are not described by the schema, and they will be ignored. + This field is a member of `oneof`_ ``source``. instances_format (str): Required. The format in which instances are given, must be @@ -271,6 +281,7 @@ class OutputConfig(proto.Message): per their schema, followed by an additional ``error`` field which as value has [google.rpc.Status][google.rpc.Status] containing only ``code`` and ``message`` fields. + This field is a member of `oneof`_ ``destination``. bigquery_destination (google.cloud.aiplatform_v1.types.BigQueryDestination): The BigQuery project or dataset location where the output is @@ -294,6 +305,7 @@ class OutputConfig(proto.Message): followed by a single "errors" column, which as values has [google.rpc.Status][google.rpc.Status] represented as a STRUCT, and containing only ``code`` and ``message``. + This field is a member of `oneof`_ ``destination``. predictions_format (str): Required. The format in which Vertex AI gives the @@ -329,11 +341,13 @@ class OutputInfo(proto.Message): Output only. The full path of the Cloud Storage directory created, into which the prediction output is written. + This field is a member of `oneof`_ ``output_location``. bigquery_output_dataset (str): Output only. The path of the BigQuery dataset created, in ``bq://projectId.bqDatasetId`` format, into which the prediction output is written. + This field is a member of `oneof`_ ``output_location``. bigquery_output_table (str): Output only. The name of the BigQuery table created, in @@ -353,6 +367,11 @@ class OutputInfo(proto.Message): name = proto.Field(proto.STRING, number=1,) display_name = proto.Field(proto.STRING, number=2,) model = proto.Field(proto.STRING, number=3,) + unmanaged_container_model = proto.Field( + proto.MESSAGE, + number=28, + message=gca_unmanaged_container_model.UnmanagedContainerModel, + ) input_config = proto.Field(proto.MESSAGE, number=4, message=InputConfig,) model_parameters = proto.Field(proto.MESSAGE, number=5, message=struct_pb2.Value,) output_config = proto.Field(proto.MESSAGE, number=6, message=OutputConfig,) diff --git a/google/cloud/aiplatform_v1/types/custom_job.py b/google/cloud/aiplatform_v1/types/custom_job.py index 0559eb8a63..846de2f622 100644 --- a/google/cloud/aiplatform_v1/types/custom_job.py +++ b/google/cloud/aiplatform_v1/types/custom_job.py @@ -148,9 +148,12 @@ class CustomJobSpec(proto.Message): {project} is a project number, as in ``12345``, and {network} is a network name. - Private services access must already be configured for the - network. If left unspecified, the job is not peered with any - network. + To specify this field, you must have already `configured VPC + Network Peering for Vertex + AI `__. + + If this field is left unspecified, the job is not peered + with any network. base_output_directory (google.cloud.aiplatform_v1.types.GcsDestination): The Cloud Storage location to store the output of this CustomJob or HyperparameterTuningJob. For @@ -178,6 +181,12 @@ class CustomJobSpec(proto.Message): ``//checkpoints/`` - AIP_TENSORBOARD_LOG_DIR = ``//logs/`` + tensorboard (str): + Optional. The name of a Vertex AI + [Tensorboard][google.cloud.aiplatform.v1.Tensorboard] + resource to which this CustomJob will upload Tensorboard + logs. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` enable_web_access (bool): Optional. Whether you want Vertex AI to enable `interactive shell @@ -202,6 +211,7 @@ class CustomJobSpec(proto.Message): base_output_directory = proto.Field( proto.MESSAGE, number=6, message=io.GcsDestination, ) + tensorboard = proto.Field(proto.STRING, number=7,) enable_web_access = proto.Field(proto.BOOL, number=10,) @@ -218,9 +228,11 @@ class WorkerPoolSpec(proto.Message): Attributes: container_spec (google.cloud.aiplatform_v1.types.ContainerSpec): The custom container task. + This field is a member of `oneof`_ ``task``. python_package_spec (google.cloud.aiplatform_v1.types.PythonPackageSpec): The Python packaged task. + This field is a member of `oneof`_ ``task``. machine_spec (google.cloud.aiplatform_v1.types.MachineSpec): Optional. Immutable. The specification of a diff --git a/google/cloud/aiplatform_v1/types/data_labeling_job.py b/google/cloud/aiplatform_v1/types/data_labeling_job.py index a3737d13c3..63ff9a0b55 100644 --- a/google/cloud/aiplatform_v1/types/data_labeling_job.py +++ b/google/cloud/aiplatform_v1/types/data_labeling_job.py @@ -179,10 +179,12 @@ class ActiveLearningConfig(proto.Message): Attributes: max_data_item_count (int): Max number of human labeled DataItems. + This field is a member of `oneof`_ ``human_labeling_budget``. max_data_item_percentage (int): Max percent of total DataItems for human labeling. + This field is a member of `oneof`_ ``human_labeling_budget``. sample_config (google.cloud.aiplatform_v1.types.SampleConfig): Active learning data sampling config. For @@ -219,11 +221,13 @@ class SampleConfig(proto.Message): initial_batch_sample_percentage (int): The percentage of data needed to be labeled in the first batch. + This field is a member of `oneof`_ ``initial_batch_sample_size``. following_batch_sample_percentage (int): The percentage of data needed to be labeled in each following batch (except the first batch). + This field is a member of `oneof`_ ``following_batch_sample_size``. sample_strategy (google.cloud.aiplatform_v1.types.SampleConfig.SampleStrategy): Field to choose sampling strategy. Sampling diff --git a/google/cloud/aiplatform_v1/types/dataset.py b/google/cloud/aiplatform_v1/types/dataset.py index 5416afad60..ef7a466d6b 100644 --- a/google/cloud/aiplatform_v1/types/dataset.py +++ b/google/cloud/aiplatform_v1/types/dataset.py @@ -113,6 +113,7 @@ class ImportDataConfig(proto.Message): gcs_source (google.cloud.aiplatform_v1.types.GcsSource): The Google Cloud Storage location for the input content. + This field is a member of `oneof`_ ``source``. data_item_labels (Sequence[google.cloud.aiplatform_v1.types.ImportDataConfig.DataItemLabelsEntry]): Labels that will be applied to newly imported DataItems. If @@ -164,6 +165,7 @@ class ExportDataConfig(proto.Message): with the corresponding annotations' schema title. Inside these sub directories, a schema.yaml will be created to describe the output format. + This field is a member of `oneof`_ ``destination``. annotations_filter (str): A filter on Annotations of the Dataset. Only Annotations on diff --git a/google/cloud/aiplatform_v1/types/endpoint.py b/google/cloud/aiplatform_v1/types/endpoint.py index 7f33d4d7f3..8ea223fc73 100644 --- a/google/cloud/aiplatform_v1/types/endpoint.py +++ b/google/cloud/aiplatform_v1/types/endpoint.py @@ -92,10 +92,22 @@ class Endpoint(proto.Message): network. If left unspecified, the Endpoint is not peered with any network. + Only one of the fields, + [network][google.cloud.aiplatform.v1.Endpoint.network] or + [enable_private_service_connect][google.cloud.aiplatform.v1.Endpoint.enable_private_service_connect], + can be set. + `Format `__: ``projects/{project}/global/networks/{network}``. Where ``{project}`` is a project number, as in ``12345``, and ``{network}`` is network name. + enable_private_service_connect (bool): + If true, expose the Endpoint via private service connect. + + Only one of the fields, + [network][google.cloud.aiplatform.v1.Endpoint.network] or + [enable_private_service_connect][google.cloud.aiplatform.v1.Endpoint.enable_private_service_connect], + can be set. model_deployment_monitoring_job (str): Output only. Resource name of the Model Monitoring job associated with this Endpoint if monitoring is enabled by @@ -118,6 +130,7 @@ class Endpoint(proto.Message): proto.MESSAGE, number=10, message=gca_encryption_spec.EncryptionSpec, ) network = proto.Field(proto.STRING, number=13,) + enable_private_service_connect = proto.Field(proto.BOOL, number=17,) model_deployment_monitoring_job = proto.Field(proto.STRING, number=14,) @@ -137,14 +150,20 @@ class DeployedModel(proto.Message): A description of resources that are dedicated to the DeployedModel, and that need a higher degree of manual configuration. + This field is a member of `oneof`_ ``prediction_resources``. automatic_resources (google.cloud.aiplatform_v1.types.AutomaticResources): A description of resources that to large degree are decided by Vertex AI, and require only a modest additional configuration. + This field is a member of `oneof`_ ``prediction_resources``. id (str): - Output only. The ID of the DeployedModel. + Immutable. The ID of the DeployedModel. If not provided upon + deployment, Vertex AI will generate a value for this ID. + + This value should be 1-10 characters, and valid characters + are /[0-9]/. model (str): Required. The name of the Model that this is the deployment of. Note that the Model may be in @@ -240,8 +259,10 @@ class DeployedModel(proto.Message): class PrivateEndpoints(proto.Message): - r"""PrivateEndpoints is used to provide paths for users to send - requests via private services access. + r"""PrivateEndpoints proto is used to provide paths for users to send + requests privately. To send request via private service access, use + predict_http_uri, explain_http_uri or health_http_uri. To send + request via private service connect, use service_attachment. Attributes: predict_http_uri (str): @@ -253,11 +274,16 @@ class PrivateEndpoints(proto.Message): health_http_uri (str): Output only. Http(s) path to send health check requests. + service_attachment (str): + Output only. The name of the service + attachment resource. Populated if private + service connect is enabled. """ predict_http_uri = proto.Field(proto.STRING, number=1,) explain_http_uri = proto.Field(proto.STRING, number=2,) health_http_uri = proto.Field(proto.STRING, number=3,) + service_attachment = proto.Field(proto.STRING, number=4,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/endpoint_service.py b/google/cloud/aiplatform_v1/types/endpoint_service.py index 19e463a721..d7bf783b4a 100644 --- a/google/cloud/aiplatform_v1/types/endpoint_service.py +++ b/google/cloud/aiplatform_v1/types/endpoint_service.py @@ -51,10 +51,21 @@ class CreateEndpointRequest(proto.Message): ``projects/{project}/locations/{location}`` endpoint (google.cloud.aiplatform_v1.types.Endpoint): Required. The Endpoint to create. + endpoint_id (str): + Immutable. The ID to use for endpoint, which will become the + final component of the endpoint resource name. If not + provided, Vertex AI will generate a value for this ID. + + This value should be 1-10 characters, and valid characters + are /[0-9]/. When using HTTP/JSON, this field is populated + based on a query string argument, such as + ``?endpoint_id=12345``. This is the fallback for fields that + are not included in either the URI or the body. """ parent = proto.Field(proto.STRING, number=1,) endpoint = proto.Field(proto.MESSAGE, number=2, message=gca_endpoint.Endpoint,) + endpoint_id = proto.Field(proto.STRING, number=4,) class CreateEndpointOperationMetadata(proto.Message): diff --git a/google/cloud/aiplatform_v1/types/execution.py b/google/cloud/aiplatform_v1/types/execution.py index 2041d131fa..52acfc61aa 100644 --- a/google/cloud/aiplatform_v1/types/execution.py +++ b/google/cloud/aiplatform_v1/types/execution.py @@ -38,7 +38,7 @@ class Execution(proto.Message): The state of this Execution. This is a property of the Execution, and does not imply or capture any ongoing process. This property is - managed by clients (such as Vertex Pipelines) + managed by clients (such as Vertex AI Pipelines) and the system does not prescribe or check the validity of state transitions. etag (str): diff --git a/google/cloud/aiplatform_v1/types/explanation.py b/google/cloud/aiplatform_v1/types/explanation.py index 9ac0afa4b8..33a688fbe0 100644 --- a/google/cloud/aiplatform_v1/types/explanation.py +++ b/google/cloud/aiplatform_v1/types/explanation.py @@ -32,6 +32,7 @@ "XraiAttribution", "SmoothGradConfig", "FeatureNoiseSigma", + "BlurBaselineConfig", "ExplanationSpecOverride", "ExplanationMetadataOverride", }, @@ -276,6 +277,7 @@ class ExplanationParameters(proto.Message): considering all subsets of features. Refer to this paper for model details: https://arxiv.org/abs/1306.4265. + This field is a member of `oneof`_ ``method``. integrated_gradients_attribution (google.cloud.aiplatform_v1.types.IntegratedGradientsAttribution): An attribution method that computes Aumann- @@ -283,6 +285,7 @@ class ExplanationParameters(proto.Message): fully differentiable structure. Refer to this paper for more details: https://arxiv.org/abs/1703.01365 + This field is a member of `oneof`_ ``method``. xrai_attribution (google.cloud.aiplatform_v1.types.XraiAttribution): An attribution method that redistributes @@ -298,6 +301,7 @@ class ExplanationParameters(proto.Message): or from diagnostic equipment, like x-rays or quality-control cameras, use Integrated Gradients instead. + This field is a member of `oneof`_ ``method``. top_k (int): If populated, returns attributions for top K @@ -376,12 +380,22 @@ class IntegratedGradientsAttribution(proto.Message): help improve the computed gradients. Refer to this paper for more details: https://arxiv.org/pdf/1706.03825.pdf + blur_baseline_config (google.cloud.aiplatform_v1.types.BlurBaselineConfig): + Config for IG with blur baseline. + When enabled, a linear path from the maximally + blurred image to the input image is created. + Using a blurred baseline instead of zero (black + image) is motivated by the BlurIG approach + explained here: https://arxiv.org/abs/2004.03383 """ step_count = proto.Field(proto.INT32, number=1,) smooth_grad_config = proto.Field( proto.MESSAGE, number=2, message="SmoothGradConfig", ) + blur_baseline_config = proto.Field( + proto.MESSAGE, number=3, message="BlurBaselineConfig", + ) class XraiAttribution(proto.Message): @@ -409,12 +423,22 @@ class XraiAttribution(proto.Message): help improve the computed gradients. Refer to this paper for more details: https://arxiv.org/pdf/1706.03825.pdf + blur_baseline_config (google.cloud.aiplatform_v1.types.BlurBaselineConfig): + Config for XRAI with blur baseline. + When enabled, a linear path from the maximally + blurred image to the input image is created. + Using a blurred baseline instead of zero (black + image) is motivated by the BlurIG approach + explained here: https://arxiv.org/abs/2004.03383 """ step_count = proto.Field(proto.INT32, number=1,) smooth_grad_config = proto.Field( proto.MESSAGE, number=2, message="SmoothGradConfig", ) + blur_baseline_config = proto.Field( + proto.MESSAGE, number=3, message="BlurBaselineConfig", + ) class SmoothGradConfig(proto.Message): @@ -449,6 +473,7 @@ class SmoothGradConfig(proto.Message): If the distribution is different per feature, set [feature_noise_sigma][google.cloud.aiplatform.v1.SmoothGradConfig.feature_noise_sigma] instead for each feature. + This field is a member of `oneof`_ ``GradientNoiseSigma``. feature_noise_sigma (google.cloud.aiplatform_v1.types.FeatureNoiseSigma): This is similar to @@ -459,6 +484,7 @@ class SmoothGradConfig(proto.Message): that are not set. If this field is unset, [noise_sigma][google.cloud.aiplatform.v1.SmoothGradConfig.noise_sigma] will be used for all features. + This field is a member of `oneof`_ ``GradientNoiseSigma``. noisy_sample_count (int): The number of gradient samples to use for approximation. The @@ -513,6 +539,26 @@ class NoiseSigmaForFeature(proto.Message): ) +class BlurBaselineConfig(proto.Message): + r"""Config for blur baseline. + When enabled, a linear path from the maximally blurred image to + the input image is created. Using a blurred baseline instead of + zero (black image) is motivated by the BlurIG approach explained + here: + https://arxiv.org/abs/2004.03383 + + Attributes: + max_blur_sigma (float): + The standard deviation of the blur kernel for + the blurred baseline. The same blurring + parameter is used for both the height and the + width dimension. If not set, the method defaults + to the zero (i.e. black for images) baseline. + """ + + max_blur_sigma = proto.Field(proto.FLOAT, number=1,) + + class ExplanationSpecOverride(proto.Message): r"""The [ExplanationSpec][google.cloud.aiplatform.v1.ExplanationSpec] entries that can be overridden at [online diff --git a/google/cloud/aiplatform_v1/types/explanation_metadata.py b/google/cloud/aiplatform_v1/types/explanation_metadata.py index 26adfe7ab7..2c6c45cd82 100644 --- a/google/cloud/aiplatform_v1/types/explanation_metadata.py +++ b/google/cloud/aiplatform_v1/types/explanation_metadata.py @@ -356,6 +356,7 @@ class OutputMetadata(proto.Message): [Attribution.output_display_name][google.cloud.aiplatform.v1.Attribution.output_display_name] is populated by locating in the mapping with [Attribution.output_index][google.cloud.aiplatform.v1.Attribution.output_index]. + This field is a member of `oneof`_ ``display_name_mapping``. display_name_mapping_key (str): Specify a field name in the prediction to look for the @@ -368,6 +369,7 @@ class OutputMetadata(proto.Message): of the outputs, so that it can be located by [Attribution.output_index][google.cloud.aiplatform.v1.Attribution.output_index] for a specific output. + This field is a member of `oneof`_ ``display_name_mapping``. output_tensor_name (str): Name of the output tensor. Required and is diff --git a/google/cloud/aiplatform_v1/types/featurestore.py b/google/cloud/aiplatform_v1/types/featurestore.py index 2377fe86a1..0f706dcffc 100644 --- a/google/cloud/aiplatform_v1/types/featurestore.py +++ b/google/cloud/aiplatform_v1/types/featurestore.py @@ -25,7 +25,7 @@ class Featurestore(proto.Message): - r"""Vertex Feature Store provides a centralized repository for + r"""Vertex AI Feature Store provides a centralized repository for organizing, storing, and serving ML features. The Featurestore is a top-level container for your features and their values. diff --git a/google/cloud/aiplatform_v1/types/featurestore_online_service.py b/google/cloud/aiplatform_v1/types/featurestore_online_service.py index f84ab2c580..d62257c4ee 100644 --- a/google/cloud/aiplatform_v1/types/featurestore_online_service.py +++ b/google/cloud/aiplatform_v1/types/featurestore_online_service.py @@ -136,6 +136,7 @@ class Data(proto.Message): Attributes: value (google.cloud.aiplatform_v1.types.FeatureValue): Feature value if a single value is requested. + This field is a member of `oneof`_ ``data``. values (google.cloud.aiplatform_v1.types.FeatureValueList): Feature values list if values, successive in @@ -143,6 +144,7 @@ class Data(proto.Message): values is greater than the number of existing Feature values, nonexistent values are omitted instead of being returned as empty. + This field is a member of `oneof`_ ``data``. """ @@ -207,30 +209,39 @@ class FeatureValue(proto.Message): Attributes: bool_value (bool): Bool type feature value. + This field is a member of `oneof`_ ``value``. double_value (float): Double type feature value. + This field is a member of `oneof`_ ``value``. int64_value (int): Int64 feature value. + This field is a member of `oneof`_ ``value``. string_value (str): String feature value. + This field is a member of `oneof`_ ``value``. bool_array_value (google.cloud.aiplatform_v1.types.BoolArray): A list of bool type feature value. + This field is a member of `oneof`_ ``value``. double_array_value (google.cloud.aiplatform_v1.types.DoubleArray): A list of double type feature value. + This field is a member of `oneof`_ ``value``. int64_array_value (google.cloud.aiplatform_v1.types.Int64Array): A list of int64 type feature value. + This field is a member of `oneof`_ ``value``. string_array_value (google.cloud.aiplatform_v1.types.StringArray): A list of string type feature value. + This field is a member of `oneof`_ ``value``. bytes_value (bytes): Bytes feature value. + This field is a member of `oneof`_ ``value``. metadata (google.cloud.aiplatform_v1.types.FeatureValue.Metadata): Metadata of feature value. @@ -245,7 +256,10 @@ class Metadata(proto.Message): is provided by user at feature ingestion time. If not, feature store will use the system timestamp when the data is ingested into feature - store. + store. For streaming ingestion, the time, + aligned by days, must be no older than five + years (1825 days) and no later than one year + (366 days) in the future. """ generate_time = proto.Field( diff --git a/google/cloud/aiplatform_v1/types/featurestore_service.py b/google/cloud/aiplatform_v1/types/featurestore_service.py index 3a665a616d..87a76d5c82 100644 --- a/google/cloud/aiplatform_v1/types/featurestore_service.py +++ b/google/cloud/aiplatform_v1/types/featurestore_service.py @@ -277,11 +277,13 @@ class ImportFeatureValuesRequest(proto.Message): feature_time_field (str): Source column that holds the Feature timestamp for all Feature values in each entity. + This field is a member of `oneof`_ ``feature_time_source``. feature_time (google.protobuf.timestamp_pb2.Timestamp): Single Feature timestamp for all entities being imported. The timestamp must not have higher than millisecond precision. + This field is a member of `oneof`_ ``feature_time_source``. entity_type (str): Required. The resource name of the EntityType grouping the @@ -416,9 +418,11 @@ class BatchReadFeatureValuesRequest(proto.Message): Values in the timestamp column must use the RFC 3339 format, e.g. ``2012-07-30T10:43:17.123Z``. + This field is a member of `oneof`_ ``read_option``. bigquery_read_instances (google.cloud.aiplatform_v1.types.BigQuerySource): Similar to csv_read_instances, but from BigQuery source. + This field is a member of `oneof`_ ``read_option``. featurestore (str): Required. The resource name of the Featurestore from which @@ -503,13 +507,23 @@ class ExportFeatureValuesRequest(proto.Message): r"""Request message for [FeaturestoreService.ExportFeatureValues][google.cloud.aiplatform.v1.FeaturestoreService.ExportFeatureValues]. + 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: snapshot_export (google.cloud.aiplatform_v1.types.ExportFeatureValuesRequest.SnapshotExport): - Exports Feature values of all entities of the - EntityType as of a snapshot time. + Exports the latest Feature values of all + entities of the EntityType within a time range. + + This field is a member of `oneof`_ ``mode``. + full_export (google.cloud.aiplatform_v1.types.ExportFeatureValuesRequest.FullExport): + Exports all historical values of all entities + of the EntityType within a time range + This field is a member of `oneof`_ ``mode``. entity_type (str): Required. The resource name of the EntityType from which to @@ -526,8 +540,8 @@ class ExportFeatureValuesRequest(proto.Message): """ class SnapshotExport(proto.Message): - r"""Describes exporting Feature values as of the snapshot - timestamp. + r"""Describes exporting the latest Feature values of all entities of the + EntityType between [start_time, snapshot_time]. Attributes: snapshot_time (google.protobuf.timestamp_pb2.Timestamp): @@ -535,15 +549,52 @@ class SnapshotExport(proto.Message): If not set, retrieve values as of now. Timestamp, if present, must not have higher than millisecond precision. + start_time (google.protobuf.timestamp_pb2.Timestamp): + Excludes Feature values with feature + generation timestamp before this timestamp. If + not set, retrieve oldest values kept in Feature + Store. Timestamp, if present, must not have + higher than millisecond precision. """ snapshot_time = proto.Field( proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp, ) + start_time = proto.Field( + proto.MESSAGE, number=2, message=timestamp_pb2.Timestamp, + ) + + class FullExport(proto.Message): + r"""Describes exporting all historical Feature values of all entities of + the EntityType between [start_time, end_time]. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Excludes Feature values with feature + generation timestamp before this timestamp. If + not set, retrieve oldest values kept in Feature + Store. Timestamp, if present, must not have + higher than millisecond precision. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Exports Feature values as of this timestamp. + If not set, retrieve values as of now. + Timestamp, if present, must not have higher than + millisecond precision. + """ + + start_time = proto.Field( + proto.MESSAGE, number=2, message=timestamp_pb2.Timestamp, + ) + end_time = proto.Field( + proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp, + ) snapshot_export = proto.Field( proto.MESSAGE, number=3, oneof="mode", message=SnapshotExport, ) + full_export = proto.Field( + proto.MESSAGE, number=7, oneof="mode", message=FullExport, + ) entity_type = proto.Field(proto.STRING, number=1,) destination = proto.Field( proto.MESSAGE, number=4, message="FeatureValueDestination", @@ -590,6 +641,7 @@ class FeatureValueDestination(proto.Message): in [FeatureValueDestination.bigquery_destination][google.cloud.aiplatform.v1.FeatureValueDestination.bigquery_destination] must refer to a table. + This field is a member of `oneof`_ ``destination``. tfrecord_destination (google.cloud.aiplatform_v1.types.TFRecordDestination): Output in TFRecord format. @@ -605,10 +657,12 @@ class FeatureValueDestination(proto.Message): STRING, STRING_ARRAY, BYTES | BYTES_LIST true -> byte_string("true"), false -> byte_string("false") BOOL, BOOL_ARRAY (true, false) | BYTES_LIST + This field is a member of `oneof`_ ``destination``. csv_destination (google.cloud.aiplatform_v1.types.CsvDestination): Output in CSV format. Array Feature value types are not allowed in CSV format. + This field is a member of `oneof`_ ``destination``. """ @@ -1206,17 +1260,17 @@ class UpdateFeaturestoreOperationMetadata(proto.Message): class ImportFeatureValuesOperationMetadata(proto.Message): - r"""Details of operations that perform import feature values. + r"""Details of operations that perform import Feature values. Attributes: generic_metadata (google.cloud.aiplatform_v1.types.GenericOperationMetadata): Operation metadata for Featurestore import - feature values. + Feature values. imported_entity_count (int): Number of entities that have been imported by the operation. imported_feature_value_count (int): - Number of feature values that have been + Number of Feature values that have been imported by the operation. invalid_row_count (int): The number of rows in input source that weren't imported due diff --git a/google/cloud/aiplatform_v1/types/index_endpoint.py b/google/cloud/aiplatform_v1/types/index_endpoint.py index 0371beba3a..6f2edb034e 100644 --- a/google/cloud/aiplatform_v1/types/index_endpoint.py +++ b/google/cloud/aiplatform_v1/types/index_endpoint.py @@ -73,8 +73,7 @@ class IndexEndpoint(proto.Message): of the original Indexes they are the deployments of. network (str): - Required. Immutable. The full name of the Google Compute - Engine + Optional. The full name of the Google Compute Engine `network `__ to which the IndexEndpoint should be peered. @@ -82,10 +81,25 @@ class IndexEndpoint(proto.Message): network. If left unspecified, the Endpoint is not peered with any network. + Only one of the fields, + [network][google.cloud.aiplatform.v1.IndexEndpoint.network] + or + [enable_private_service_connect][google.cloud.aiplatform.v1.IndexEndpoint.enable_private_service_connect], + can be set. + `Format `__: projects/{project}/global/networks/{network}. Where {project} is a project number, as in '12345', and {network} is network name. + enable_private_service_connect (bool): + Optional. If true, expose the IndexEndpoint via private + service connect. + + Only one of the fields, + [network][google.cloud.aiplatform.v1.IndexEndpoint.network] + or + [enable_private_service_connect][google.cloud.aiplatform.v1.IndexEndpoint.enable_private_service_connect], + can be set. """ name = proto.Field(proto.STRING, number=1,) @@ -99,6 +113,7 @@ class IndexEndpoint(proto.Message): create_time = proto.Field(proto.MESSAGE, number=7, message=timestamp_pb2.Timestamp,) update_time = proto.Field(proto.MESSAGE, number=8, message=timestamp_pb2.Timestamp,) network = proto.Field(proto.STRING, number=9,) + enable_private_service_connect = proto.Field(proto.BOOL, number=10,) class DeployedIndex(proto.Message): @@ -255,16 +270,24 @@ class AuthProvider(proto.Message): class IndexPrivateEndpoints(proto.Message): - r"""IndexPrivateEndpoints proto is used to provide paths for - users to send requests via private services access. + r"""IndexPrivateEndpoints proto is used to provide paths for users to + send requests via private endpoints (e.g. private service access, + private service connect). To send request via private service + access, use match_grpc_address. To send request via private service + connect, use service_attachment. Attributes: match_grpc_address (str): Output only. The ip address used to send match gRPC requests. + service_attachment (str): + Output only. The name of the service + attachment resource. Populated if private + service connect is enabled. """ match_grpc_address = proto.Field(proto.STRING, number=1,) + service_attachment = proto.Field(proto.STRING, number=2,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/index_endpoint_service.py b/google/cloud/aiplatform_v1/types/index_endpoint_service.py index 2dfd523bc0..f3d57b0f19 100644 --- a/google/cloud/aiplatform_v1/types/index_endpoint_service.py +++ b/google/cloud/aiplatform_v1/types/index_endpoint_service.py @@ -36,6 +36,9 @@ "UndeployIndexRequest", "UndeployIndexResponse", "UndeployIndexOperationMetadata", + "MutateDeployedIndexRequest", + "MutateDeployedIndexResponse", + "MutateDeployedIndexOperationMetadata", }, ) @@ -289,4 +292,58 @@ class UndeployIndexOperationMetadata(proto.Message): ) +class MutateDeployedIndexRequest(proto.Message): + r"""Request message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1.IndexEndpointService.MutateDeployedIndex]. + + Attributes: + index_endpoint (str): + Required. The name of the IndexEndpoint resource into which + to deploy an Index. Format: + ``projects/{project}/locations/{location}/indexEndpoints/{index_endpoint}`` + deployed_index (google.cloud.aiplatform_v1.types.DeployedIndex): + Required. The DeployedIndex to be updated within the + IndexEndpoint. Currently, the updatable fields are + [DeployedIndex][automatic_resources] and + [DeployedIndex][dedicated_resources] + """ + + index_endpoint = proto.Field(proto.STRING, number=1,) + deployed_index = proto.Field( + proto.MESSAGE, number=2, message=gca_index_endpoint.DeployedIndex, + ) + + +class MutateDeployedIndexResponse(proto.Message): + r"""Response message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1.IndexEndpointService.MutateDeployedIndex]. + + Attributes: + deployed_index (google.cloud.aiplatform_v1.types.DeployedIndex): + The DeployedIndex that had been updated in + the IndexEndpoint. + """ + + deployed_index = proto.Field( + proto.MESSAGE, number=1, message=gca_index_endpoint.DeployedIndex, + ) + + +class MutateDeployedIndexOperationMetadata(proto.Message): + r"""Runtime operation information for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1.IndexEndpointService.MutateDeployedIndex]. + + Attributes: + generic_metadata (google.cloud.aiplatform_v1.types.GenericOperationMetadata): + The operation generic information. + deployed_index_id (str): + The unique index id specified by user + """ + + generic_metadata = proto.Field( + proto.MESSAGE, number=1, message=operation.GenericOperationMetadata, + ) + deployed_index_id = proto.Field(proto.STRING, number=2,) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/job_service.py b/google/cloud/aiplatform_v1/types/job_service.py index f61d307fe3..67d1df1469 100644 --- a/google/cloud/aiplatform_v1/types/job_service.py +++ b/google/cloud/aiplatform_v1/types/job_service.py @@ -631,7 +631,7 @@ class SearchModelDeploymentMonitoringStatsAnomaliesRequest(proto.Message): \`projects/{project}/locations/{location}/modelDeploymentMonitoringJobs/{model_deployment_monitoring_job} deployed_model_id (str): Required. The DeployedModel ID of the - [google.cloud.aiplatform.master.ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. + [ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. feature_display_name (str): The feature display name. If specified, only return the stats belonging to this feature. Format: diff --git a/google/cloud/aiplatform_v1/types/migratable_resource.py b/google/cloud/aiplatform_v1/types/migratable_resource.py index 8c049e4d1a..659e178e8e 100644 --- a/google/cloud/aiplatform_v1/types/migratable_resource.py +++ b/google/cloud/aiplatform_v1/types/migratable_resource.py @@ -38,18 +38,22 @@ class MigratableResource(proto.Message): ml_engine_model_version (google.cloud.aiplatform_v1.types.MigratableResource.MlEngineModelVersion): Output only. Represents one Version in ml.googleapis.com. + This field is a member of `oneof`_ ``resource``. automl_model (google.cloud.aiplatform_v1.types.MigratableResource.AutomlModel): Output only. Represents one Model in automl.googleapis.com. + This field is a member of `oneof`_ ``resource``. automl_dataset (google.cloud.aiplatform_v1.types.MigratableResource.AutomlDataset): Output only. Represents one Dataset in automl.googleapis.com. + This field is a member of `oneof`_ ``resource``. data_labeling_dataset (google.cloud.aiplatform_v1.types.MigratableResource.DataLabelingDataset): Output only. Represents one Dataset in datalabeling.googleapis.com. + This field is a member of `oneof`_ ``resource``. last_migrate_time (google.protobuf.timestamp_pb2.Timestamp): Output only. Timestamp when the last diff --git a/google/cloud/aiplatform_v1/types/migration_service.py b/google/cloud/aiplatform_v1/types/migration_service.py index 6b904d9c48..50b6bd4785 100644 --- a/google/cloud/aiplatform_v1/types/migration_service.py +++ b/google/cloud/aiplatform_v1/types/migration_service.py @@ -141,19 +141,23 @@ class MigrateResourceRequest(proto.Message): migrate_ml_engine_model_version_config (google.cloud.aiplatform_v1.types.MigrateResourceRequest.MigrateMlEngineModelVersionConfig): Config for migrating Version in ml.googleapis.com to Vertex AI's Model. + This field is a member of `oneof`_ ``request``. migrate_automl_model_config (google.cloud.aiplatform_v1.types.MigrateResourceRequest.MigrateAutomlModelConfig): Config for migrating Model in automl.googleapis.com to Vertex AI's Model. + This field is a member of `oneof`_ ``request``. migrate_automl_dataset_config (google.cloud.aiplatform_v1.types.MigrateResourceRequest.MigrateAutomlDatasetConfig): Config for migrating Dataset in automl.googleapis.com to Vertex AI's Dataset. + This field is a member of `oneof`_ ``request``. migrate_data_labeling_dataset_config (google.cloud.aiplatform_v1.types.MigrateResourceRequest.MigrateDataLabelingDatasetConfig): Config for migrating Dataset in datalabeling.googleapis.com to Vertex AI's Dataset. + This field is a member of `oneof`_ ``request``. """ @@ -309,9 +313,11 @@ class MigrateResourceResponse(proto.Message): Attributes: dataset (str): Migrated Dataset's resource name. + This field is a member of `oneof`_ ``migrated_resource``. model (str): Migrated Model's resource name. + This field is a member of `oneof`_ ``migrated_resource``. migratable_resource (google.cloud.aiplatform_v1.types.MigratableResource): Before migration, the identifier in @@ -353,12 +359,15 @@ class PartialResult(proto.Message): error (google.rpc.status_pb2.Status): The error result of the migration request in case of failure. + This field is a member of `oneof`_ ``result``. model (str): Migrated model resource name. + This field is a member of `oneof`_ ``result``. dataset (str): Migrated dataset resource name. + This field is a member of `oneof`_ ``result``. request (google.cloud.aiplatform_v1.types.MigrateResourceRequest): It's the same as the value in diff --git a/google/cloud/aiplatform_v1/types/model_deployment_monitoring_job.py b/google/cloud/aiplatform_v1/types/model_deployment_monitoring_job.py index 3bbf2db2a3..21aba235b2 100644 --- a/google/cloud/aiplatform_v1/types/model_deployment_monitoring_job.py +++ b/google/cloud/aiplatform_v1/types/model_deployment_monitoring_job.py @@ -162,9 +162,10 @@ class ModelDeploymentMonitoringJob(proto.Message): resources of this ModelDeploymentMonitoringJob will be secured by this key. enable_monitoring_pipeline_logs (bool): - If true, the scheduled monitoring pipeline status logs are - sent to Google Cloud Logging. Please note the logs incur - cost, which are subject to `Cloud Logging + If true, the scheduled monitoring pipeline logs are sent to + Google Cloud Logging, including pipeline status and + anomalies detected. Please note the logs incur cost, which + are subject to `Cloud Logging pricing `__. error (google.rpc.status_pb2.Status): Output only. Only populated when the job's state is diff --git a/google/cloud/aiplatform_v1/types/model_monitoring.py b/google/cloud/aiplatform_v1/types/model_monitoring.py index cf8e243443..9f81bedba0 100644 --- a/google/cloud/aiplatform_v1/types/model_monitoring.py +++ b/google/cloud/aiplatform_v1/types/model_monitoring.py @@ -44,8 +44,8 @@ class ModelMonitoringObjectiveConfig(proto.Message): prediction_drift_detection_config (google.cloud.aiplatform_v1.types.ModelMonitoringObjectiveConfig.PredictionDriftDetectionConfig): The config for drift of prediction data. explanation_config (google.cloud.aiplatform_v1.types.ModelMonitoringObjectiveConfig.ExplanationConfig): - The config for integrated with Explainable - AI. + The config for integrating with Vertex + Explainable AI. """ class TrainingDataset(proto.Message): @@ -62,14 +62,17 @@ class TrainingDataset(proto.Message): dataset (str): The resource name of the Dataset used to train this Model. + This field is a member of `oneof`_ ``data_source``. gcs_source (google.cloud.aiplatform_v1.types.GcsSource): The Google Cloud Storage uri of the unmanaged Dataset used to train this Model. + This field is a member of `oneof`_ ``data_source``. bigquery_source (google.cloud.aiplatform_v1.types.BigQuerySource): The BigQuery table of the unmanaged Dataset used to train this Model. + This field is a member of `oneof`_ ``data_source``. data_format (str): Data format of the dataset, only applicable @@ -157,14 +160,14 @@ class PredictionDriftDetectionConfig(proto.Message): ) class ExplanationConfig(proto.Message): - r"""The config for integrated with Explainable AI. Only applicable if - the Model has explanation_spec populated. + r"""The config for integrating with Vertex Explainable AI. Only + applicable if the Model has explanation_spec populated. Attributes: enable_feature_attributes (bool): - If want to analyze the Explainable AI feature - attribute scores or not. If set to true, Vertex - AI will log the feature attributions from + If want to analyze the Vertex Explainable AI + feature attribute scores or not. If set to true, + Vertex AI will log the feature attributions from explain response and do the skew/drift detection for them. explanation_baseline (google.cloud.aiplatform_v1.types.ModelMonitoringObjectiveConfig.ExplanationConfig.ExplanationBaseline): @@ -189,9 +192,11 @@ class ExplanationBaseline(proto.Message): gcs (google.cloud.aiplatform_v1.types.GcsDestination): Cloud Storage location for BatchExplain output. + This field is a member of `oneof`_ ``destination``. bigquery (google.cloud.aiplatform_v1.types.BigQueryDestination): BigQuery location for BatchExplain output. + This field is a member of `oneof`_ ``destination``. prediction_format (google.cloud.aiplatform_v1.types.ModelMonitoringObjectiveConfig.ExplanationConfig.ExplanationBaseline.PredictionFormat): The storage format of the predictions @@ -241,14 +246,21 @@ class PredictionFormat(proto.Enum): class ModelMonitoringAlertConfig(proto.Message): - r"""Next ID: 2 + r"""Next ID: 3 .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: email_alert_config (google.cloud.aiplatform_v1.types.ModelMonitoringAlertConfig.EmailAlertConfig): Email alert config. + This field is a member of `oneof`_ ``alert``. + enable_logging (bool): + Dump the anomalies to Cloud Logging. The anomalies will be + put to json payload encoded from proto + [google.cloud.aiplatform.logging.ModelMonitoringAnomaliesLogEntry][]. + This can be further sinked to Pub/Sub or any other services + supported by Cloud Logging. """ class EmailAlertConfig(proto.Message): @@ -264,6 +276,7 @@ class EmailAlertConfig(proto.Message): email_alert_config = proto.Field( proto.MESSAGE, number=1, oneof="alert", message=EmailAlertConfig, ) + enable_logging = proto.Field(proto.BOOL, number=2,) class ThresholdConfig(proto.Message): @@ -286,6 +299,7 @@ class ThresholdConfig(proto.Message): Each feature must have a non-zero threshold if they need to be monitored. Otherwise no alert will be triggered for that feature. + This field is a member of `oneof`_ ``threshold``. """ diff --git a/google/cloud/aiplatform_v1/types/pipeline_job.py b/google/cloud/aiplatform_v1/types/pipeline_job.py index 681e91a368..9c31981b51 100644 --- a/google/cloud/aiplatform_v1/types/pipeline_job.py +++ b/google/cloud/aiplatform_v1/types/pipeline_job.py @@ -116,11 +116,16 @@ class RuntimeConfig(proto.Message): Attributes: parameters (Sequence[google.cloud.aiplatform_v1.types.PipelineJob.RuntimeConfig.ParametersEntry]): - Deprecated. Use [RuntimeConfig.parameter_values] instead. - The runtime parameters of the PipelineJob. The parameters - will be passed into + Deprecated. Use + [RuntimeConfig.parameter_values][google.cloud.aiplatform.v1.PipelineJob.RuntimeConfig.parameter_values] + instead. The runtime parameters of the PipelineJob. The + parameters will be passed into [PipelineJob.pipeline_spec][google.cloud.aiplatform.v1.PipelineJob.pipeline_spec] - to replace the placeholders at runtime. + to replace the placeholders at runtime. This field is used + by pipelines built using + ``PipelineJob.pipeline_spec.schema_version`` 2.0.0 or lower, + such as pipelines built using Kubeflow Pipelines SDK 1.8 or + lower. gcs_output_directory (str): Required. A path in a Cloud Storage bucket, which will be treated as the root output directory of the pipeline. It is @@ -134,7 +139,11 @@ class RuntimeConfig(proto.Message): The runtime parameters of the PipelineJob. The parameters will be passed into [PipelineJob.pipeline_spec][google.cloud.aiplatform.v1.PipelineJob.pipeline_spec] - to replace the placeholders at runtime. + to replace the placeholders at runtime. This field is used + by pipelines built using + ``PipelineJob.pipeline_spec.schema_version`` 2.1.0, such as + pipelines built using Kubeflow Pipelines SDK 1.9 or higher + and the v2 DSL. """ parameters = proto.MapField( @@ -316,10 +325,12 @@ class PipelineTaskExecutorDetail(proto.Message): container_detail (google.cloud.aiplatform_v1.types.PipelineTaskExecutorDetail.ContainerDetail): Output only. The detailed info for a container executor. + This field is a member of `oneof`_ ``details``. custom_job_detail (google.cloud.aiplatform_v1.types.PipelineTaskExecutorDetail.CustomJobDetail): Output only. The detailed info for a custom job executor. + This field is a member of `oneof`_ ``details``. """ diff --git a/google/cloud/aiplatform_v1/types/pipeline_service.py b/google/cloud/aiplatform_v1/types/pipeline_service.py index 28d1309a10..0c54e44a0b 100644 --- a/google/cloud/aiplatform_v1/types/pipeline_service.py +++ b/google/cloud/aiplatform_v1/types/pipeline_service.py @@ -227,6 +227,7 @@ class ListPipelineJobsRequest(proto.Message): comparisons, and ``:`` wildcard. for example, can check if pipeline's display_name contains *step* by doing display_name:"*step*" + - ``state``: Supports ``=`` and ``!=`` comparisons. - ``create_time``: Supports ``=``, ``!=``, ``<``, ``>``, ``<=``, and ``>=`` comparisons. Values must be in RFC 3339 format. diff --git a/google/cloud/aiplatform_v1/types/study.py b/google/cloud/aiplatform_v1/types/study.py index be142a2544..e8d807a2dd 100644 --- a/google/cloud/aiplatform_v1/types/study.py +++ b/google/cloud/aiplatform_v1/types/study.py @@ -27,7 +27,8 @@ class Study(proto.Message): - r"""A message representing a Study. + r"""LINT.IfChange + A message representing a Study. Attributes: name (str): @@ -97,13 +98,14 @@ class Trial(proto.Message): client_id (str): Output only. The identifier of the client that originally requested this Trial. Each client is identified by a unique - client_id. When a client asks for a suggestion, Vizier will - assign it a Trial. The client should evaluate the Trial, - complete it, and report back to Vizier. If suggestion is - asked again by same client_id before the Trial is completed, - the same Trial will be returned. Multiple clients with - different client_ids can ask for suggestions simultaneously, - each of them will get their own Trial. + client_id. When a client asks for a suggestion, Vertex AI + Vizier will assign it a Trial. The client should evaluate + the Trial, complete it, and report back to Vertex AI Vizier. + If suggestion is asked again by same client_id before the + Trial is completed, the same Trial will be returned. + Multiple clients with different client_ids can ask for + suggestions simultaneously, each of them will get their own + Trial. infeasible_reason (str): Output only. A human readable string describing why the Trial is infeasible. This is set only if Trial state is @@ -187,10 +189,12 @@ class StudySpec(proto.Message): decay_curve_stopping_spec (google.cloud.aiplatform_v1.types.StudySpec.DecayCurveAutomatedStoppingSpec): The automated early stopping spec using decay curve rule. + This field is a member of `oneof`_ ``automated_stopping_spec``. median_automated_stopping_spec (google.cloud.aiplatform_v1.types.StudySpec.MedianAutomatedStoppingSpec): The automated early stopping spec using median rule. + This field is a member of `oneof`_ ``automated_stopping_spec``. metrics (Sequence[google.cloud.aiplatform_v1.types.StudySpec.MetricSpec]): Required. Metric specs for the Study. @@ -200,9 +204,9 @@ class StudySpec(proto.Message): The search algorithm specified for the Study. observation_noise (google.cloud.aiplatform_v1.types.StudySpec.ObservationNoise): The observation noise level of the study. - Currently only supported by the Vizier service. - Not supported by HyperparamterTuningJob or - TrainingPipeline. + Currently only supported by the Vertex AI Vizier + service. Not supported by HyperparamterTuningJob + or TrainingPipeline. measurement_selection_type (google.cloud.aiplatform_v1.types.StudySpec.MeasurementSelectionType): Describe which measurement selection type will be used @@ -276,15 +280,19 @@ class ParameterSpec(proto.Message): Attributes: double_value_spec (google.cloud.aiplatform_v1.types.StudySpec.ParameterSpec.DoubleValueSpec): The value spec for a 'DOUBLE' parameter. + This field is a member of `oneof`_ ``parameter_value_spec``. integer_value_spec (google.cloud.aiplatform_v1.types.StudySpec.ParameterSpec.IntegerValueSpec): The value spec for an 'INTEGER' parameter. + This field is a member of `oneof`_ ``parameter_value_spec``. categorical_value_spec (google.cloud.aiplatform_v1.types.StudySpec.ParameterSpec.CategoricalValueSpec): The value spec for a 'CATEGORICAL' parameter. + This field is a member of `oneof`_ ``parameter_value_spec``. discrete_value_spec (google.cloud.aiplatform_v1.types.StudySpec.ParameterSpec.DiscreteValueSpec): The value spec for a 'DISCRETE' parameter. + This field is a member of `oneof`_ ``parameter_value_spec``. parameter_id (str): Required. The ID of the parameter. Must not @@ -323,8 +331,9 @@ class DoubleValueSpec(proto.Message): to be a relatively good starting point. Unset value signals that there is no offered starting point. - Currently only supported by the Vizier service. Not - supported by HyperparamterTuningJob or TrainingPipeline. + Currently only supported by the Vertex AI Vizier service. + Not supported by HyperparamterTuningJob or TrainingPipeline. + This field is a member of `oneof`_ ``_default_value``. """ @@ -347,8 +356,9 @@ class IntegerValueSpec(proto.Message): to be a relatively good starting point. Unset value signals that there is no offered starting point. - Currently only supported by the Vizier service. Not - supported by HyperparamterTuningJob or TrainingPipeline. + Currently only supported by the Vertex AI Vizier service. + Not supported by HyperparamterTuningJob or TrainingPipeline. + This field is a member of `oneof`_ ``_default_value``. """ @@ -369,6 +379,7 @@ class CategoricalValueSpec(proto.Message): Currently only supported by the Vizier service. Not supported by HyperparamterTuningJob or TrainingPipeline. + This field is a member of `oneof`_ ``_default_value``. """ @@ -394,6 +405,7 @@ class DiscreteValueSpec(proto.Message): Currently only supported by the Vizier service. Not supported by HyperparamterTuningJob or TrainingPipeline. + This field is a member of `oneof`_ ``_default_value``. """ @@ -415,14 +427,17 @@ class ConditionalParameterSpec(proto.Message): parent_discrete_values (google.cloud.aiplatform_v1.types.StudySpec.ParameterSpec.ConditionalParameterSpec.DiscreteValueCondition): The spec for matching values from a parent parameter of ``DISCRETE`` type. + This field is a member of `oneof`_ ``parent_value_condition``. parent_int_values (google.cloud.aiplatform_v1.types.StudySpec.ParameterSpec.ConditionalParameterSpec.IntValueCondition): The spec for matching values from a parent parameter of ``INTEGER`` type. + This field is a member of `oneof`_ ``parent_value_condition``. parent_categorical_values (google.cloud.aiplatform_v1.types.StudySpec.ParameterSpec.ConditionalParameterSpec.CategoricalValueCondition): The spec for matching values from a parent parameter of ``CATEGORICAL`` type. + This field is a member of `oneof`_ ``parent_value_condition``. parameter_spec (google.cloud.aiplatform_v1.types.StudySpec.ParameterSpec): Required. The spec for a conditional diff --git a/google/cloud/aiplatform_v1/types/tensorboard.py b/google/cloud/aiplatform_v1/types/tensorboard.py new file mode 100644 index 0000000000..6836011844 --- /dev/null +++ b/google/cloud/aiplatform_v1/types/tensorboard.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.aiplatform_v1.types import encryption_spec as gca_encryption_spec +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.cloud.aiplatform.v1", manifest={"Tensorboard",}, +) + + +class Tensorboard(proto.Message): + r"""Tensorboard is a physical database that stores users' + training metrics. A default Tensorboard is provided in each + region of a GCP project. If needed users can also create extra + Tensorboards in their projects. + + Attributes: + name (str): + Output only. Name of the Tensorboard. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + display_name (str): + Required. User provided name of this + Tensorboard. + description (str): + Description of this Tensorboard. + encryption_spec (google.cloud.aiplatform_v1.types.EncryptionSpec): + Customer-managed encryption key spec for a + Tensorboard. If set, this Tensorboard and all + sub-resources of this Tensorboard will be + secured by this key. + blob_storage_path_prefix (str): + Output only. Consumer project Cloud Storage + path prefix used to store blob data, which can + either be a bucket or directory. Does not end + with a '/'. + run_count (int): + Output only. The number of Runs stored in + this Tensorboard. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp when this Tensorboard + was created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp when this Tensorboard + was last updated. + labels (Sequence[google.cloud.aiplatform_v1.types.Tensorboard.LabelsEntry]): + The labels with user-defined metadata to + organize your Tensorboards. + Label keys and values can be no longer than 64 + characters (Unicode codepoints), can only + contain lowercase letters, numeric characters, + underscores and dashes. International characters + are allowed. No more than 64 user labels can be + associated with one Tensorboard (System labels + are excluded). + + See https://goo.gl/xmQnxf for more information + and examples of labels. System reserved label + keys are prefixed with + "aiplatform.googleapis.com/" and are immutable. + etag (str): + Used to perform a consistent read-modify- + rite updates. If not set, a blind "overwrite" + update happens. + """ + + name = proto.Field(proto.STRING, number=1,) + display_name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) + encryption_spec = proto.Field( + proto.MESSAGE, number=11, message=gca_encryption_spec.EncryptionSpec, + ) + blob_storage_path_prefix = proto.Field(proto.STRING, number=10,) + run_count = proto.Field(proto.INT32, number=5,) + create_time = proto.Field(proto.MESSAGE, number=6, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=7, message=timestamp_pb2.Timestamp,) + labels = proto.MapField(proto.STRING, proto.STRING, number=8,) + etag = proto.Field(proto.STRING, number=9,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/tensorboard_data.py b/google/cloud/aiplatform_v1/types/tensorboard_data.py new file mode 100644 index 0000000000..4d049fa62c --- /dev/null +++ b/google/cloud/aiplatform_v1/types/tensorboard_data.py @@ -0,0 +1,163 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.aiplatform_v1.types import tensorboard_time_series +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.cloud.aiplatform.v1", + manifest={ + "TimeSeriesData", + "TimeSeriesDataPoint", + "Scalar", + "TensorboardTensor", + "TensorboardBlobSequence", + "TensorboardBlob", + }, +) + + +class TimeSeriesData(proto.Message): + r"""All the data stored in a TensorboardTimeSeries. + + Attributes: + tensorboard_time_series_id (str): + Required. The ID of the + TensorboardTimeSeries, which will become the + final component of the TensorboardTimeSeries' + resource name + value_type (google.cloud.aiplatform_v1.types.TensorboardTimeSeries.ValueType): + Required. Immutable. The value type of this + time series. All the values in this time series + data must match this value type. + values (Sequence[google.cloud.aiplatform_v1.types.TimeSeriesDataPoint]): + Required. Data points in this time series. + """ + + tensorboard_time_series_id = proto.Field(proto.STRING, number=1,) + value_type = proto.Field( + proto.ENUM, + number=2, + enum=tensorboard_time_series.TensorboardTimeSeries.ValueType, + ) + values = proto.RepeatedField( + proto.MESSAGE, number=3, message="TimeSeriesDataPoint", + ) + + +class TimeSeriesDataPoint(proto.Message): + r"""A TensorboardTimeSeries data point. + + 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: + scalar (google.cloud.aiplatform_v1.types.Scalar): + A scalar value. + + This field is a member of `oneof`_ ``value``. + tensor (google.cloud.aiplatform_v1.types.TensorboardTensor): + A tensor value. + + This field is a member of `oneof`_ ``value``. + blobs (google.cloud.aiplatform_v1.types.TensorboardBlobSequence): + A blob sequence value. + + This field is a member of `oneof`_ ``value``. + wall_time (google.protobuf.timestamp_pb2.Timestamp): + Wall clock timestamp when this data point is + generated by the end user. + step (int): + Step index of this data point within the run. + """ + + scalar = proto.Field(proto.MESSAGE, number=3, oneof="value", message="Scalar",) + tensor = proto.Field( + proto.MESSAGE, number=4, oneof="value", message="TensorboardTensor", + ) + blobs = proto.Field( + proto.MESSAGE, number=5, oneof="value", message="TensorboardBlobSequence", + ) + wall_time = proto.Field(proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp,) + step = proto.Field(proto.INT64, number=2,) + + +class Scalar(proto.Message): + r"""One point viewable on a scalar metric plot. + + Attributes: + value (float): + Value of the point at this step / timestamp. + """ + + value = proto.Field(proto.DOUBLE, number=1,) + + +class TensorboardTensor(proto.Message): + r"""One point viewable on a tensor metric plot. + + Attributes: + value (bytes): + Required. Serialized form of + https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/tensor.proto + version_number (int): + Optional. Version number of TensorProto used to serialize + [value][google.cloud.aiplatform.v1.TensorboardTensor.value]. + """ + + value = proto.Field(proto.BYTES, number=1,) + version_number = proto.Field(proto.INT32, number=2,) + + +class TensorboardBlobSequence(proto.Message): + r"""One point viewable on a blob metric plot, but mostly just a wrapper + message to work around repeated fields can't be used directly within + ``oneof`` fields. + + Attributes: + values (Sequence[google.cloud.aiplatform_v1.types.TensorboardBlob]): + List of blobs contained within the sequence. + """ + + values = proto.RepeatedField(proto.MESSAGE, number=1, message="TensorboardBlob",) + + +class TensorboardBlob(proto.Message): + r"""One blob (e.g, image, graph) viewable on a blob metric plot. + + Attributes: + id (str): + Output only. A URI safe key uniquely + identifying a blob. Can be used to locate the + blob stored in the Cloud Storage bucket of the + consumer project. + data (bytes): + Optional. The bytes of the blob is not + present unless it's returned by the + ReadTensorboardBlobData endpoint. + """ + + id = proto.Field(proto.STRING, number=1,) + data = proto.Field(proto.BYTES, number=2,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/tensorboard_experiment.py b/google/cloud/aiplatform_v1/types/tensorboard_experiment.py new file mode 100644 index 0000000000..2c9057fd48 --- /dev/null +++ b/google/cloud/aiplatform_v1/types/tensorboard_experiment.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.cloud.aiplatform.v1", manifest={"TensorboardExperiment",}, +) + + +class TensorboardExperiment(proto.Message): + r"""A TensorboardExperiment is a group of TensorboardRuns, that + are typically the results of a training job run, in a + Tensorboard. + + Attributes: + name (str): + Output only. Name of the TensorboardExperiment. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + display_name (str): + User provided name of this + TensorboardExperiment. + description (str): + Description of this TensorboardExperiment. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp when this + TensorboardExperiment was created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp when this + TensorboardExperiment was last updated. + labels (Sequence[google.cloud.aiplatform_v1.types.TensorboardExperiment.LabelsEntry]): + The labels with user-defined metadata to organize your + Datasets. + + Label keys and values can be no longer than 64 characters + (Unicode codepoints), can only contain lowercase letters, + numeric characters, underscores and dashes. International + characters are allowed. No more than 64 user labels can be + associated with one Dataset (System labels are excluded). + + See https://goo.gl/xmQnxf for more information and examples + of labels. System reserved label keys are prefixed with + "aiplatform.googleapis.com/" and are immutable. Following + system labels exist for each Dataset: + + - "aiplatform.googleapis.com/dataset_metadata_schema": + + - output only, its value is the + [metadata_schema's][metadata_schema_uri] title. + etag (str): + Used to perform consistent read-modify-write + updates. If not set, a blind "overwrite" update + happens. + source (str): + Immutable. Source of the + TensorboardExperiment. Example: a custom + training job. + """ + + name = proto.Field(proto.STRING, number=1,) + display_name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) + create_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=5, message=timestamp_pb2.Timestamp,) + labels = proto.MapField(proto.STRING, proto.STRING, number=6,) + etag = proto.Field(proto.STRING, number=7,) + source = proto.Field(proto.STRING, number=8,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/tensorboard_run.py b/google/cloud/aiplatform_v1/types/tensorboard_run.py new file mode 100644 index 0000000000..c127a2c8f4 --- /dev/null +++ b/google/cloud/aiplatform_v1/types/tensorboard_run.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.cloud.aiplatform.v1", manifest={"TensorboardRun",}, +) + + +class TensorboardRun(proto.Message): + r"""TensorboardRun maps to a specific execution of a training job + with a given set of hyperparameter values, model definition, + dataset, etc + + Attributes: + name (str): + Output only. Name of the TensorboardRun. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + display_name (str): + Required. User provided name of this + TensorboardRun. This value must be unique among + all TensorboardRuns belonging to the same parent + TensorboardExperiment. + description (str): + Description of this TensorboardRun. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp when this + TensorboardRun was created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp when this + TensorboardRun was last updated. + labels (Sequence[google.cloud.aiplatform_v1.types.TensorboardRun.LabelsEntry]): + The labels with user-defined metadata to organize your + TensorboardRuns. + + This field will be used to filter and visualize Runs in the + Tensorboard UI. For example, a Vertex AI training job can + set a label aiplatform.googleapis.com/training_job_id=xxxxx + to all the runs created within that job. An end user can set + a label experiment_id=xxxxx for all the runs produced in a + Jupyter notebook. These runs can be grouped by a label value + and visualized together in the Tensorboard UI. + + Label keys and values can be no longer than 64 characters + (Unicode codepoints), can only contain lowercase letters, + numeric characters, underscores and dashes. International + characters are allowed. No more than 64 user labels can be + associated with one TensorboardRun (System labels are + excluded). + + See https://goo.gl/xmQnxf for more information and examples + of labels. System reserved label keys are prefixed with + "aiplatform.googleapis.com/" and are immutable. + etag (str): + Used to perform a consistent read-modify- + rite updates. If not set, a blind "overwrite" + update happens. + """ + + name = proto.Field(proto.STRING, number=1,) + display_name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) + create_time = proto.Field(proto.MESSAGE, number=6, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=7, message=timestamp_pb2.Timestamp,) + labels = proto.MapField(proto.STRING, proto.STRING, number=8,) + etag = proto.Field(proto.STRING, number=9,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/tensorboard_service.py b/google/cloud/aiplatform_v1/types/tensorboard_service.py new file mode 100644 index 0000000000..9fe1b141c0 --- /dev/null +++ b/google/cloud/aiplatform_v1/types/tensorboard_service.py @@ -0,0 +1,1002 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.aiplatform_v1.types import operation +from google.cloud.aiplatform_v1.types import tensorboard as gca_tensorboard +from google.cloud.aiplatform_v1.types import tensorboard_data +from google.cloud.aiplatform_v1.types import ( + tensorboard_experiment as gca_tensorboard_experiment, +) +from google.cloud.aiplatform_v1.types import tensorboard_run as gca_tensorboard_run +from google.cloud.aiplatform_v1.types import ( + tensorboard_time_series as gca_tensorboard_time_series, +) +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.cloud.aiplatform.v1", + manifest={ + "CreateTensorboardRequest", + "GetTensorboardRequest", + "ListTensorboardsRequest", + "ListTensorboardsResponse", + "UpdateTensorboardRequest", + "DeleteTensorboardRequest", + "CreateTensorboardExperimentRequest", + "GetTensorboardExperimentRequest", + "ListTensorboardExperimentsRequest", + "ListTensorboardExperimentsResponse", + "UpdateTensorboardExperimentRequest", + "DeleteTensorboardExperimentRequest", + "BatchCreateTensorboardRunsRequest", + "BatchCreateTensorboardRunsResponse", + "CreateTensorboardRunRequest", + "GetTensorboardRunRequest", + "ReadTensorboardBlobDataRequest", + "ReadTensorboardBlobDataResponse", + "ListTensorboardRunsRequest", + "ListTensorboardRunsResponse", + "UpdateTensorboardRunRequest", + "DeleteTensorboardRunRequest", + "BatchCreateTensorboardTimeSeriesRequest", + "BatchCreateTensorboardTimeSeriesResponse", + "CreateTensorboardTimeSeriesRequest", + "GetTensorboardTimeSeriesRequest", + "ListTensorboardTimeSeriesRequest", + "ListTensorboardTimeSeriesResponse", + "UpdateTensorboardTimeSeriesRequest", + "DeleteTensorboardTimeSeriesRequest", + "BatchReadTensorboardTimeSeriesDataRequest", + "BatchReadTensorboardTimeSeriesDataResponse", + "ReadTensorboardTimeSeriesDataRequest", + "ReadTensorboardTimeSeriesDataResponse", + "WriteTensorboardExperimentDataRequest", + "WriteTensorboardExperimentDataResponse", + "WriteTensorboardRunDataRequest", + "WriteTensorboardRunDataResponse", + "ExportTensorboardTimeSeriesDataRequest", + "ExportTensorboardTimeSeriesDataResponse", + "CreateTensorboardOperationMetadata", + "UpdateTensorboardOperationMetadata", + }, +) + + +class CreateTensorboardRequest(proto.Message): + r"""Request message for + [TensorboardService.CreateTensorboard][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboard]. + + Attributes: + parent (str): + Required. The resource name of the Location to create the + Tensorboard in. Format: + ``projects/{project}/locations/{location}`` + tensorboard (google.cloud.aiplatform_v1.types.Tensorboard): + Required. The Tensorboard to create. + """ + + parent = proto.Field(proto.STRING, number=1,) + tensorboard = proto.Field( + proto.MESSAGE, number=2, message=gca_tensorboard.Tensorboard, + ) + + +class GetTensorboardRequest(proto.Message): + r"""Request message for + [TensorboardService.GetTensorboard][google.cloud.aiplatform.v1.TensorboardService.GetTensorboard]. + + Attributes: + name (str): + Required. The name of the Tensorboard resource. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + """ + + name = proto.Field(proto.STRING, number=1,) + + +class ListTensorboardsRequest(proto.Message): + r"""Request message for + [TensorboardService.ListTensorboards][google.cloud.aiplatform.v1.TensorboardService.ListTensorboards]. + + Attributes: + parent (str): + Required. The resource name of the Location to list + Tensorboards. Format: + ``projects/{project}/locations/{location}`` + filter (str): + Lists the Tensorboards that match the filter + expression. + page_size (int): + The maximum number of Tensorboards to return. + The service may return fewer than this value. If + unspecified, at most 100 Tensorboards will be + returned. The maximum value is 100; values above + 100 will be coerced to 100. + page_token (str): + A page token, received from a previous + [TensorboardService.ListTensorboards][google.cloud.aiplatform.v1.TensorboardService.ListTensorboards] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [TensorboardService.ListTensorboards][google.cloud.aiplatform.v1.TensorboardService.ListTensorboards] + must match the call that provided the page token. + order_by (str): + Field to use to sort the list. + read_mask (google.protobuf.field_mask_pb2.FieldMask): + Mask specifying which fields to read. + """ + + parent = proto.Field(proto.STRING, number=1,) + filter = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + page_token = proto.Field(proto.STRING, number=4,) + order_by = proto.Field(proto.STRING, number=5,) + read_mask = proto.Field(proto.MESSAGE, number=6, message=field_mask_pb2.FieldMask,) + + +class ListTensorboardsResponse(proto.Message): + r"""Response message for + [TensorboardService.ListTensorboards][google.cloud.aiplatform.v1.TensorboardService.ListTensorboards]. + + Attributes: + tensorboards (Sequence[google.cloud.aiplatform_v1.types.Tensorboard]): + The Tensorboards mathching the request. + next_page_token (str): + A token, which can be sent as + [ListTensorboardsRequest.page_token][google.cloud.aiplatform.v1.ListTensorboardsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + tensorboards = proto.RepeatedField( + proto.MESSAGE, number=1, message=gca_tensorboard.Tensorboard, + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class UpdateTensorboardRequest(proto.Message): + r"""Request message for + [TensorboardService.UpdateTensorboard][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboard]. + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Field mask is used to specify the fields to be + overwritten in the Tensorboard 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 if new values are + specified. + tensorboard (google.cloud.aiplatform_v1.types.Tensorboard): + Required. The Tensorboard's ``name`` field is used to + identify the Tensorboard to be updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + """ + + update_mask = proto.Field( + proto.MESSAGE, number=1, message=field_mask_pb2.FieldMask, + ) + tensorboard = proto.Field( + proto.MESSAGE, number=2, message=gca_tensorboard.Tensorboard, + ) + + +class DeleteTensorboardRequest(proto.Message): + r"""Request message for + [TensorboardService.DeleteTensorboard][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboard]. + + Attributes: + name (str): + Required. The name of the Tensorboard to be deleted. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + """ + + name = proto.Field(proto.STRING, number=1,) + + +class CreateTensorboardExperimentRequest(proto.Message): + r"""Request message for + [TensorboardService.CreateTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboardExperiment]. + + Attributes: + parent (str): + Required. The resource name of the Tensorboard to create the + TensorboardExperiment in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}`` + tensorboard_experiment (google.cloud.aiplatform_v1.types.TensorboardExperiment): + The TensorboardExperiment to create. + tensorboard_experiment_id (str): + Required. The ID to use for the Tensorboard experiment, + which will become the final component of the Tensorboard + experiment's resource name. + + This value should be 1-128 characters, and valid characters + are /[a-z][0-9]-/. + """ + + parent = proto.Field(proto.STRING, number=1,) + tensorboard_experiment = proto.Field( + proto.MESSAGE, + number=2, + message=gca_tensorboard_experiment.TensorboardExperiment, + ) + tensorboard_experiment_id = proto.Field(proto.STRING, number=3,) + + +class GetTensorboardExperimentRequest(proto.Message): + r"""Request message for + [TensorboardService.GetTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.GetTensorboardExperiment]. + + Attributes: + name (str): + Required. The name of the TensorboardExperiment resource. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + """ + + name = proto.Field(proto.STRING, number=1,) + + +class ListTensorboardExperimentsRequest(proto.Message): + r"""Request message for + [TensorboardService.ListTensorboardExperiments][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardExperiments]. + + Attributes: + parent (str): + Required. The resource name of the + Tensorboard to list TensorboardExperiments. + Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}' + filter (str): + Lists the TensorboardExperiments that match + the filter expression. + page_size (int): + The maximum number of TensorboardExperiments + to return. The service may return fewer than + this value. If unspecified, at most 50 + TensorboardExperiments will be returned. The + maximum value is 1000; values above 1000 will be + coerced to 1000. + page_token (str): + A page token, received from a previous + [TensorboardService.ListTensorboardExperiments][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardExperiments] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [TensorboardService.ListTensorboardExperiments][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardExperiments] + must match the call that provided the page token. + order_by (str): + Field to use to sort the list. + read_mask (google.protobuf.field_mask_pb2.FieldMask): + Mask specifying which fields to read. + """ + + parent = proto.Field(proto.STRING, number=1,) + filter = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + page_token = proto.Field(proto.STRING, number=4,) + order_by = proto.Field(proto.STRING, number=5,) + read_mask = proto.Field(proto.MESSAGE, number=6, message=field_mask_pb2.FieldMask,) + + +class ListTensorboardExperimentsResponse(proto.Message): + r"""Response message for + [TensorboardService.ListTensorboardExperiments][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardExperiments]. + + Attributes: + tensorboard_experiments (Sequence[google.cloud.aiplatform_v1.types.TensorboardExperiment]): + The TensorboardExperiments mathching the + request. + next_page_token (str): + A token, which can be sent as + [ListTensorboardExperimentsRequest.page_token][google.cloud.aiplatform.v1.ListTensorboardExperimentsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + tensorboard_experiments = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gca_tensorboard_experiment.TensorboardExperiment, + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class UpdateTensorboardExperimentRequest(proto.Message): + r"""Request message for + [TensorboardService.UpdateTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboardExperiment]. + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Field mask is used to specify the fields to be + overwritten in the TensorboardExperiment 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 if new + values are specified. + tensorboard_experiment (google.cloud.aiplatform_v1.types.TensorboardExperiment): + Required. The TensorboardExperiment's ``name`` field is used + to identify the TensorboardExperiment to be updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + """ + + update_mask = proto.Field( + proto.MESSAGE, number=1, message=field_mask_pb2.FieldMask, + ) + tensorboard_experiment = proto.Field( + proto.MESSAGE, + number=2, + message=gca_tensorboard_experiment.TensorboardExperiment, + ) + + +class DeleteTensorboardExperimentRequest(proto.Message): + r"""Request message for + [TensorboardService.DeleteTensorboardExperiment][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboardExperiment]. + + Attributes: + name (str): + Required. The name of the TensorboardExperiment to be + deleted. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + """ + + name = proto.Field(proto.STRING, number=1,) + + +class BatchCreateTensorboardRunsRequest(proto.Message): + r"""Request message for + [TensorboardService.BatchCreateTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardRuns]. + + Attributes: + parent (str): + Required. The resource name of the TensorboardExperiment to + create the TensorboardRuns in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + The parent field in the CreateTensorboardRunRequest messages + must match this field. + requests (Sequence[google.cloud.aiplatform_v1.types.CreateTensorboardRunRequest]): + Required. The request message specifying the + TensorboardRuns to create. A maximum of 1000 + TensorboardRuns can be created in a batch. + """ + + parent = proto.Field(proto.STRING, number=1,) + requests = proto.RepeatedField( + proto.MESSAGE, number=2, message="CreateTensorboardRunRequest", + ) + + +class BatchCreateTensorboardRunsResponse(proto.Message): + r"""Response message for + [TensorboardService.BatchCreateTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardRuns]. + + Attributes: + tensorboard_runs (Sequence[google.cloud.aiplatform_v1.types.TensorboardRun]): + The created TensorboardRuns. + """ + + tensorboard_runs = proto.RepeatedField( + proto.MESSAGE, number=1, message=gca_tensorboard_run.TensorboardRun, + ) + + +class CreateTensorboardRunRequest(proto.Message): + r"""Request message for + [TensorboardService.CreateTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboardRun]. + + Attributes: + parent (str): + Required. The resource name of the TensorboardExperiment to + create the TensorboardRun in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + tensorboard_run (google.cloud.aiplatform_v1.types.TensorboardRun): + Required. The TensorboardRun to create. + tensorboard_run_id (str): + Required. The ID to use for the Tensorboard run, which will + become the final component of the Tensorboard run's resource + name. + + This value should be 1-128 characters, and valid characters + are /[a-z][0-9]-/. + """ + + parent = proto.Field(proto.STRING, number=1,) + tensorboard_run = proto.Field( + proto.MESSAGE, number=2, message=gca_tensorboard_run.TensorboardRun, + ) + tensorboard_run_id = proto.Field(proto.STRING, number=3,) + + +class GetTensorboardRunRequest(proto.Message): + r"""Request message for + [TensorboardService.GetTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.GetTensorboardRun]. + + Attributes: + name (str): + Required. The name of the TensorboardRun resource. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + """ + + name = proto.Field(proto.STRING, number=1,) + + +class ReadTensorboardBlobDataRequest(proto.Message): + r"""Request message for + [TensorboardService.ReadTensorboardBlobData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardBlobData]. + + Attributes: + time_series (str): + Required. The resource name of the TensorboardTimeSeries to + list Blobs. Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}' + blob_ids (Sequence[str]): + IDs of the blobs to read. + """ + + time_series = proto.Field(proto.STRING, number=1,) + blob_ids = proto.RepeatedField(proto.STRING, number=2,) + + +class ReadTensorboardBlobDataResponse(proto.Message): + r"""Response message for + [TensorboardService.ReadTensorboardBlobData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardBlobData]. + + Attributes: + blobs (Sequence[google.cloud.aiplatform_v1.types.TensorboardBlob]): + Blob messages containing blob bytes. + """ + + blobs = proto.RepeatedField( + proto.MESSAGE, number=1, message=tensorboard_data.TensorboardBlob, + ) + + +class ListTensorboardRunsRequest(proto.Message): + r"""Request message for + [TensorboardService.ListTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardRuns]. + + Attributes: + parent (str): + Required. The resource name of the + TensorboardExperiment to list TensorboardRuns. + Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}' + filter (str): + Lists the TensorboardRuns that match the + filter expression. + page_size (int): + The maximum number of TensorboardRuns to + return. The service may return fewer than this + value. If unspecified, at most 50 + TensorboardRuns will be returned. The maximum + value is 1000; values above 1000 will be coerced + to 1000. + page_token (str): + A page token, received from a previous + [TensorboardService.ListTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardRuns] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [TensorboardService.ListTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardRuns] + must match the call that provided the page token. + order_by (str): + Field to use to sort the list. + read_mask (google.protobuf.field_mask_pb2.FieldMask): + Mask specifying which fields to read. + """ + + parent = proto.Field(proto.STRING, number=1,) + filter = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + page_token = proto.Field(proto.STRING, number=4,) + order_by = proto.Field(proto.STRING, number=5,) + read_mask = proto.Field(proto.MESSAGE, number=6, message=field_mask_pb2.FieldMask,) + + +class ListTensorboardRunsResponse(proto.Message): + r"""Response message for + [TensorboardService.ListTensorboardRuns][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardRuns]. + + Attributes: + tensorboard_runs (Sequence[google.cloud.aiplatform_v1.types.TensorboardRun]): + The TensorboardRuns mathching the request. + next_page_token (str): + A token, which can be sent as + [ListTensorboardRunsRequest.page_token][google.cloud.aiplatform.v1.ListTensorboardRunsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + tensorboard_runs = proto.RepeatedField( + proto.MESSAGE, number=1, message=gca_tensorboard_run.TensorboardRun, + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class UpdateTensorboardRunRequest(proto.Message): + r"""Request message for + [TensorboardService.UpdateTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboardRun]. + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Field mask is used to specify the fields to be + overwritten in the TensorboardRun 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 if new values are + specified. + tensorboard_run (google.cloud.aiplatform_v1.types.TensorboardRun): + Required. The TensorboardRun's ``name`` field is used to + identify the TensorboardRun to be updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + """ + + update_mask = proto.Field( + proto.MESSAGE, number=1, message=field_mask_pb2.FieldMask, + ) + tensorboard_run = proto.Field( + proto.MESSAGE, number=2, message=gca_tensorboard_run.TensorboardRun, + ) + + +class DeleteTensorboardRunRequest(proto.Message): + r"""Request message for + [TensorboardService.DeleteTensorboardRun][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboardRun]. + + Attributes: + name (str): + Required. The name of the TensorboardRun to be deleted. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + """ + + name = proto.Field(proto.STRING, number=1,) + + +class BatchCreateTensorboardTimeSeriesRequest(proto.Message): + r"""Request message for + [TensorboardService.BatchCreateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardTimeSeries]. + + Attributes: + parent (str): + Required. The resource name of the TensorboardExperiment to + create the TensorboardTimeSeries in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + The TensorboardRuns referenced by the parent fields in the + CreateTensorboardTimeSeriesRequest messages must be sub + resources of this TensorboardExperiment. + requests (Sequence[google.cloud.aiplatform_v1.types.CreateTensorboardTimeSeriesRequest]): + Required. The request message specifying the + TensorboardTimeSeries to create. A maximum of + 1000 TensorboardTimeSeries can be created in a + batch. + """ + + parent = proto.Field(proto.STRING, number=1,) + requests = proto.RepeatedField( + proto.MESSAGE, number=2, message="CreateTensorboardTimeSeriesRequest", + ) + + +class BatchCreateTensorboardTimeSeriesResponse(proto.Message): + r"""Response message for + [TensorboardService.BatchCreateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.BatchCreateTensorboardTimeSeries]. + + Attributes: + tensorboard_time_series (Sequence[google.cloud.aiplatform_v1.types.TensorboardTimeSeries]): + The created TensorboardTimeSeries. + """ + + tensorboard_time_series = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gca_tensorboard_time_series.TensorboardTimeSeries, + ) + + +class CreateTensorboardTimeSeriesRequest(proto.Message): + r"""Request message for + [TensorboardService.CreateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.CreateTensorboardTimeSeries]. + + Attributes: + parent (str): + Required. The resource name of the TensorboardRun to create + the TensorboardTimeSeries in. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + tensorboard_time_series_id (str): + Optional. The user specified unique ID to use for the + TensorboardTimeSeries, which will become the final component + of the TensorboardTimeSeries's resource name. This value + should match "[a-z0-9][a-z0-9-]{0, 127}". + tensorboard_time_series (google.cloud.aiplatform_v1.types.TensorboardTimeSeries): + Required. The TensorboardTimeSeries to + create. + """ + + parent = proto.Field(proto.STRING, number=1,) + tensorboard_time_series_id = proto.Field(proto.STRING, number=3,) + tensorboard_time_series = proto.Field( + proto.MESSAGE, + number=2, + message=gca_tensorboard_time_series.TensorboardTimeSeries, + ) + + +class GetTensorboardTimeSeriesRequest(proto.Message): + r"""Request message for + [TensorboardService.GetTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.GetTensorboardTimeSeries]. + + Attributes: + name (str): + Required. The name of the TensorboardTimeSeries resource. + Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + """ + + name = proto.Field(proto.STRING, number=1,) + + +class ListTensorboardTimeSeriesRequest(proto.Message): + r"""Request message for + [TensorboardService.ListTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardTimeSeries]. + + Attributes: + parent (str): + Required. The resource name of the + TensorboardRun to list TensorboardTimeSeries. + Format: + 'projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}' + filter (str): + Lists the TensorboardTimeSeries that match + the filter expression. + page_size (int): + The maximum number of TensorboardTimeSeries + to return. The service may return fewer than + this value. If unspecified, at most 50 + TensorboardTimeSeries will be returned. The + maximum value is 1000; values above 1000 will be + coerced to 1000. + page_token (str): + A page token, received from a previous + [TensorboardService.ListTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardTimeSeries] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [TensorboardService.ListTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardTimeSeries] + must match the call that provided the page token. + order_by (str): + Field to use to sort the list. + read_mask (google.protobuf.field_mask_pb2.FieldMask): + Mask specifying which fields to read. + """ + + parent = proto.Field(proto.STRING, number=1,) + filter = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + page_token = proto.Field(proto.STRING, number=4,) + order_by = proto.Field(proto.STRING, number=5,) + read_mask = proto.Field(proto.MESSAGE, number=6, message=field_mask_pb2.FieldMask,) + + +class ListTensorboardTimeSeriesResponse(proto.Message): + r"""Response message for + [TensorboardService.ListTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.ListTensorboardTimeSeries]. + + Attributes: + tensorboard_time_series (Sequence[google.cloud.aiplatform_v1.types.TensorboardTimeSeries]): + The TensorboardTimeSeries mathching the + request. + next_page_token (str): + A token, which can be sent as + [ListTensorboardTimeSeriesRequest.page_token][google.cloud.aiplatform.v1.ListTensorboardTimeSeriesRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + tensorboard_time_series = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gca_tensorboard_time_series.TensorboardTimeSeries, + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class UpdateTensorboardTimeSeriesRequest(proto.Message): + r"""Request message for + [TensorboardService.UpdateTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.UpdateTensorboardTimeSeries]. + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. Field mask is used to specify the fields to be + overwritten in the TensorboardTimeSeries 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 if new + values are specified. + tensorboard_time_series (google.cloud.aiplatform_v1.types.TensorboardTimeSeries): + Required. The TensorboardTimeSeries' ``name`` field is used + to identify the TensorboardTimeSeries to be updated. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + """ + + update_mask = proto.Field( + proto.MESSAGE, number=1, message=field_mask_pb2.FieldMask, + ) + tensorboard_time_series = proto.Field( + proto.MESSAGE, + number=2, + message=gca_tensorboard_time_series.TensorboardTimeSeries, + ) + + +class DeleteTensorboardTimeSeriesRequest(proto.Message): + r"""Request message for + [TensorboardService.DeleteTensorboardTimeSeries][google.cloud.aiplatform.v1.TensorboardService.DeleteTensorboardTimeSeries]. + + Attributes: + name (str): + Required. The name of the TensorboardTimeSeries to be + deleted. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + """ + + name = proto.Field(proto.STRING, number=1,) + + +class BatchReadTensorboardTimeSeriesDataRequest(proto.Message): + r"""Request message for + [TensorboardService.BatchReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.BatchReadTensorboardTimeSeriesData]. + + Attributes: + tensorboard (str): + Required. The resource name of the Tensorboard containing + TensorboardTimeSeries to read data from. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}``. + The TensorboardTimeSeries referenced by + [time_series][google.cloud.aiplatform.v1.BatchReadTensorboardTimeSeriesDataRequest.time_series] + must be sub resources of this Tensorboard. + time_series (Sequence[str]): + Required. The resource names of the TensorboardTimeSeries to + read data from. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + """ + + tensorboard = proto.Field(proto.STRING, number=1,) + time_series = proto.RepeatedField(proto.STRING, number=2,) + + +class BatchReadTensorboardTimeSeriesDataResponse(proto.Message): + r"""Response message for + [TensorboardService.BatchReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.BatchReadTensorboardTimeSeriesData]. + + Attributes: + time_series_data (Sequence[google.cloud.aiplatform_v1.types.TimeSeriesData]): + The returned time series data. + """ + + time_series_data = proto.RepeatedField( + proto.MESSAGE, number=1, message=tensorboard_data.TimeSeriesData, + ) + + +class ReadTensorboardTimeSeriesDataRequest(proto.Message): + r"""Request message for + [TensorboardService.ReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardTimeSeriesData]. + + Attributes: + tensorboard_time_series (str): + Required. The resource name of the TensorboardTimeSeries to + read data from. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + max_data_points (int): + The maximum number of TensorboardTimeSeries' + data to return. + This value should be a positive integer. + This value can be set to -1 to return all data. + filter (str): + Reads the TensorboardTimeSeries' data that + match the filter expression. + """ + + tensorboard_time_series = proto.Field(proto.STRING, number=1,) + max_data_points = proto.Field(proto.INT32, number=2,) + filter = proto.Field(proto.STRING, number=3,) + + +class ReadTensorboardTimeSeriesDataResponse(proto.Message): + r"""Response message for + [TensorboardService.ReadTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ReadTensorboardTimeSeriesData]. + + Attributes: + time_series_data (google.cloud.aiplatform_v1.types.TimeSeriesData): + The returned time series data. + """ + + time_series_data = proto.Field( + proto.MESSAGE, number=1, message=tensorboard_data.TimeSeriesData, + ) + + +class WriteTensorboardExperimentDataRequest(proto.Message): + r"""Request message for + [TensorboardService.WriteTensorboardExperimentData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardExperimentData]. + + Attributes: + tensorboard_experiment (str): + Required. The resource name of the TensorboardExperiment to + write data to. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}`` + write_run_data_requests (Sequence[google.cloud.aiplatform_v1.types.WriteTensorboardRunDataRequest]): + Required. Requests containing per-run + TensorboardTimeSeries data to write. + """ + + tensorboard_experiment = proto.Field(proto.STRING, number=1,) + write_run_data_requests = proto.RepeatedField( + proto.MESSAGE, number=2, message="WriteTensorboardRunDataRequest", + ) + + +class WriteTensorboardExperimentDataResponse(proto.Message): + r"""Response message for + [TensorboardService.WriteTensorboardExperimentData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardExperimentData]. + + """ + + +class WriteTensorboardRunDataRequest(proto.Message): + r"""Request message for + [TensorboardService.WriteTensorboardRunData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardRunData]. + + Attributes: + tensorboard_run (str): + Required. The resource name of the TensorboardRun to write + data to. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}`` + time_series_data (Sequence[google.cloud.aiplatform_v1.types.TimeSeriesData]): + Required. The TensorboardTimeSeries data to + write. Values with in a time series are indexed + by their step value. Repeated writes to the same + step will overwrite the existing value for that + step. + The upper limit of data points per write request + is 5000. + """ + + tensorboard_run = proto.Field(proto.STRING, number=1,) + time_series_data = proto.RepeatedField( + proto.MESSAGE, number=2, message=tensorboard_data.TimeSeriesData, + ) + + +class WriteTensorboardRunDataResponse(proto.Message): + r"""Response message for + [TensorboardService.WriteTensorboardRunData][google.cloud.aiplatform.v1.TensorboardService.WriteTensorboardRunData]. + + """ + + +class ExportTensorboardTimeSeriesDataRequest(proto.Message): + r"""Request message for + [TensorboardService.ExportTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ExportTensorboardTimeSeriesData]. + + Attributes: + tensorboard_time_series (str): + Required. The resource name of the TensorboardTimeSeries to + export data from. Format: + ``projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}`` + filter (str): + Exports the TensorboardTimeSeries' data that + match the filter expression. + page_size (int): + The maximum number of data points to return per page. The + default page_size will be 1000. Values must be between 1 and + 10000. Values above 10000 will be coerced to 10000. + page_token (str): + A page token, received from a previous + [TensorboardService.ExportTensorboardTimeSeries][] call. + Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [TensorboardService.ExportTensorboardTimeSeries][] must + match the call that provided the page token. + order_by (str): + Field to use to sort the + TensorboardTimeSeries' data. By default, + TensorboardTimeSeries' data will be returned in + a pseudo random order. + """ + + tensorboard_time_series = proto.Field(proto.STRING, number=1,) + filter = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + page_token = proto.Field(proto.STRING, number=4,) + order_by = proto.Field(proto.STRING, number=5,) + + +class ExportTensorboardTimeSeriesDataResponse(proto.Message): + r"""Response message for + [TensorboardService.ExportTensorboardTimeSeriesData][google.cloud.aiplatform.v1.TensorboardService.ExportTensorboardTimeSeriesData]. + + Attributes: + time_series_data_points (Sequence[google.cloud.aiplatform_v1.types.TimeSeriesDataPoint]): + The returned time series data points. + next_page_token (str): + A token, which can be sent as + [ExportTensorboardTimeSeriesRequest.page_token][] to + retrieve the next page. If this field is omitted, there are + no subsequent pages. + """ + + @property + def raw_page(self): + return self + + time_series_data_points = proto.RepeatedField( + proto.MESSAGE, number=1, message=tensorboard_data.TimeSeriesDataPoint, + ) + next_page_token = proto.Field(proto.STRING, number=2,) + + +class CreateTensorboardOperationMetadata(proto.Message): + r"""Details of operations that perform create Tensorboard. + + Attributes: + generic_metadata (google.cloud.aiplatform_v1.types.GenericOperationMetadata): + Operation metadata for Tensorboard. + """ + + generic_metadata = proto.Field( + proto.MESSAGE, number=1, message=operation.GenericOperationMetadata, + ) + + +class UpdateTensorboardOperationMetadata(proto.Message): + r"""Details of operations that perform update Tensorboard. + + Attributes: + generic_metadata (google.cloud.aiplatform_v1.types.GenericOperationMetadata): + Operation metadata for Tensorboard. + """ + + generic_metadata = proto.Field( + proto.MESSAGE, number=1, message=operation.GenericOperationMetadata, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/tensorboard_time_series.py b/google/cloud/aiplatform_v1/types/tensorboard_time_series.py new file mode 100644 index 0000000000..04c0f661b7 --- /dev/null +++ b/google/cloud/aiplatform_v1/types/tensorboard_time_series.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.cloud.aiplatform.v1", manifest={"TensorboardTimeSeries",}, +) + + +class TensorboardTimeSeries(proto.Message): + r"""TensorboardTimeSeries maps to times series produced in + training runs + + Attributes: + name (str): + Output only. Name of the + TensorboardTimeSeries. + display_name (str): + Required. User provided name of this + TensorboardTimeSeries. This value should be + unique among all TensorboardTimeSeries resources + belonging to the same TensorboardRun resource + (parent resource). + description (str): + Description of this TensorboardTimeSeries. + value_type (google.cloud.aiplatform_v1.types.TensorboardTimeSeries.ValueType): + Required. Immutable. Type of + TensorboardTimeSeries value. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp when this + TensorboardTimeSeries was created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp when this + TensorboardTimeSeries was last updated. + etag (str): + Used to perform a consistent read-modify- + rite updates. If not set, a blind "overwrite" + update happens. + plugin_name (str): + Immutable. Name of the plugin this time + series pertain to. Such as Scalar, Tensor, Blob + plugin_data (bytes): + Data of the current plugin, with the size + limited to 65KB. + metadata (google.cloud.aiplatform_v1.types.TensorboardTimeSeries.Metadata): + Output only. Scalar, Tensor, or Blob metadata + for this TensorboardTimeSeries. + """ + + class ValueType(proto.Enum): + r"""An enum representing the value type of a + TensorboardTimeSeries. + """ + VALUE_TYPE_UNSPECIFIED = 0 + SCALAR = 1 + TENSOR = 2 + BLOB_SEQUENCE = 3 + + class Metadata(proto.Message): + r"""Describes metadata for a TensorboardTimeSeries. + + Attributes: + max_step (int): + Output only. Max step index of all data + points within a TensorboardTimeSeries. + max_wall_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Max wall clock timestamp of all + data points within a TensorboardTimeSeries. + max_blob_sequence_length (int): + Output only. The largest blob sequence length (number of + blobs) of all data points in this time series, if its + ValueType is BLOB_SEQUENCE. + """ + + max_step = proto.Field(proto.INT64, number=1,) + max_wall_time = proto.Field( + proto.MESSAGE, number=2, message=timestamp_pb2.Timestamp, + ) + max_blob_sequence_length = proto.Field(proto.INT64, number=3,) + + name = proto.Field(proto.STRING, number=1,) + display_name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) + value_type = proto.Field(proto.ENUM, number=4, enum=ValueType,) + create_time = proto.Field(proto.MESSAGE, number=5, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=6, message=timestamp_pb2.Timestamp,) + etag = proto.Field(proto.STRING, number=7,) + plugin_name = proto.Field(proto.STRING, number=8,) + plugin_data = proto.Field(proto.BYTES, number=9,) + metadata = proto.Field(proto.MESSAGE, number=10, message=Metadata,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/training_pipeline.py b/google/cloud/aiplatform_v1/types/training_pipeline.py index be85a3cefd..93f4449ece 100644 --- a/google/cloud/aiplatform_v1/types/training_pipeline.py +++ b/google/cloud/aiplatform_v1/types/training_pipeline.py @@ -33,6 +33,7 @@ "FilterSplit", "PredefinedSplit", "TimestampSplit", + "StratifiedSplit", }, ) @@ -189,19 +190,29 @@ class InputDataConfig(proto.Message): fraction_split (google.cloud.aiplatform_v1.types.FractionSplit): Split based on fractions defining the size of each set. + This field is a member of `oneof`_ ``split``. filter_split (google.cloud.aiplatform_v1.types.FilterSplit): Split based on the provided filters for each set. + This field is a member of `oneof`_ ``split``. predefined_split (google.cloud.aiplatform_v1.types.PredefinedSplit): Supported only for tabular Datasets. Split based on a predefined key. + This field is a member of `oneof`_ ``split``. timestamp_split (google.cloud.aiplatform_v1.types.TimestampSplit): Supported only for tabular Datasets. Split based on the timestamp of the input data pieces. + + This field is a member of `oneof`_ ``split``. + stratified_split (google.cloud.aiplatform_v1.types.StratifiedSplit): + Supported only for tabular Datasets. + Split based on the distribution of the specified + column. + This field is a member of `oneof`_ ``split``. gcs_destination (google.cloud.aiplatform_v1.types.GcsDestination): The Cloud Storage location where the training data is to be @@ -228,6 +239,7 @@ class InputDataConfig(proto.Message): - AIP_TEST_DATA_URI = "gcs_destination/dataset---/test-*.${AIP_DATA_FORMAT}". + This field is a member of `oneof`_ ``destination``. bigquery_destination (google.cloud.aiplatform_v1.types.BigQueryDestination): Only applicable to custom training with tabular Dataset with @@ -252,6 +264,7 @@ class InputDataConfig(proto.Message): - AIP_TEST_DATA_URI = "bigquery_destination.dataset\_\ **\ .test". + This field is a member of `oneof`_ ``destination``. dataset_id (str): Required. The ID of the Dataset in the same Project and @@ -316,6 +329,9 @@ class InputDataConfig(proto.Message): timestamp_split = proto.Field( proto.MESSAGE, number=5, oneof="split", message="TimestampSplit", ) + stratified_split = proto.Field( + proto.MESSAGE, number=12, oneof="split", message="StratifiedSplit", + ) gcs_destination = proto.Field( proto.MESSAGE, number=8, oneof="destination", message=io.GcsDestination, ) @@ -450,4 +466,45 @@ class TimestampSplit(proto.Message): key = proto.Field(proto.STRING, number=4,) +class StratifiedSplit(proto.Message): + r"""Assigns input data to the training, validation, and test sets so + that the distribution of values found in the categorical column (as + specified by the ``key`` field) is mirrored within each split. The + fraction values determine the relative sizes of the splits. + + For example, if the specified column has three values, with 50% of + the rows having value "A", 25% value "B", and 25% value "C", and the + split fractions are specified as 80/10/10, then the training set + will constitute 80% of the training data, with about 50% of the + training set rows having the value "A" for the specified column, + about 25% having the value "B", and about 25% having the value "C". + + Only the top 500 occurring values are used; any values not in the + top 500 values are randomly assigned to a split. If less than three + rows contain a specific value, those rows are randomly assigned. + + Supported only for tabular Datasets. + + Attributes: + training_fraction (float): + The fraction of the input data that is to be + used to train the Model. + validation_fraction (float): + The fraction of the input data that is to be + used to validate the Model. + test_fraction (float): + The fraction of the input data that is to be + used to evaluate the Model. + key (str): + Required. The key is a name of one of the + Dataset's data columns. The key provided must be + for a categorical column. + """ + + training_fraction = proto.Field(proto.DOUBLE, number=1,) + validation_fraction = proto.Field(proto.DOUBLE, number=2,) + test_fraction = proto.Field(proto.DOUBLE, number=3,) + key = proto.Field(proto.STRING, number=4,) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/unmanaged_container_model.py b/google/cloud/aiplatform_v1/types/unmanaged_container_model.py new file mode 100644 index 0000000000..07deefc70e --- /dev/null +++ b/google/cloud/aiplatform_v1/types/unmanaged_container_model.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.aiplatform_v1.types import model + + +__protobuf__ = proto.module( + package="google.cloud.aiplatform.v1", manifest={"UnmanagedContainerModel",}, +) + + +class UnmanagedContainerModel(proto.Message): + r"""Contains model information necessary to perform batch + prediction without requiring a full model import. + + Attributes: + artifact_uri (str): + The path to the directory containing the + Model artifact and any of its supporting files. + predict_schemata (google.cloud.aiplatform_v1.types.PredictSchemata): + Contains the schemata used in Model's + predictions and explanations + container_spec (google.cloud.aiplatform_v1.types.ModelContainerSpec): + Input only. The specification of the + container that is to be used when deploying this + Model. + """ + + artifact_uri = proto.Field(proto.STRING, number=1,) + predict_schemata = proto.Field( + proto.MESSAGE, number=2, message=model.PredictSchemata, + ) + container_spec = proto.Field( + proto.MESSAGE, number=3, message=model.ModelContainerSpec, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1/types/user_action_reference.py b/google/cloud/aiplatform_v1/types/user_action_reference.py index 36ac95e653..ff3bd449c7 100644 --- a/google/cloud/aiplatform_v1/types/user_action_reference.py +++ b/google/cloud/aiplatform_v1/types/user_action_reference.py @@ -39,11 +39,13 @@ class UserActionReference(proto.Message): operation. Resource name of the long running operation. Format: 'projects/{project}/locations/{location}/operations/{operation}' + This field is a member of `oneof`_ ``reference``. data_labeling_job (str): For API calls that start a LabelingJob. Resource name of the LabelingJob. Format: 'projects/{project}/locations/{location}/dataLabelingJobs/{data_labeling_job}' + This field is a member of `oneof`_ ``reference``. method (str): The method name of the API RPC call. For diff --git a/google/cloud/aiplatform_v1/types/value.py b/google/cloud/aiplatform_v1/types/value.py index a404fe407a..4c6d8ae0ca 100644 --- a/google/cloud/aiplatform_v1/types/value.py +++ b/google/cloud/aiplatform_v1/types/value.py @@ -32,12 +32,15 @@ class Value(proto.Message): Attributes: int_value (int): An integer value. + This field is a member of `oneof`_ ``value``. double_value (float): A double value. + This field is a member of `oneof`_ ``value``. string_value (str): A string value. + This field is a member of `oneof`_ ``value``. """ diff --git a/google/cloud/aiplatform_v1beta1/__init__.py b/google/cloud/aiplatform_v1beta1/__init__.py index 3c5353af83..801ae9f5b3 100644 --- a/google/cloud/aiplatform_v1beta1/__init__.py +++ b/google/cloud/aiplatform_v1beta1/__init__.py @@ -112,6 +112,7 @@ from .types.event import Event from .types.execution import Execution from .types.explanation import Attribution +from .types.explanation import BlurBaselineConfig from .types.explanation import Explanation from .types.explanation import ExplanationMetadataOverride from .types.explanation import ExplanationParameters @@ -189,6 +190,9 @@ from .types.index_endpoint_service import GetIndexEndpointRequest from .types.index_endpoint_service import ListIndexEndpointsRequest from .types.index_endpoint_service import ListIndexEndpointsResponse +from .types.index_endpoint_service import MutateDeployedIndexOperationMetadata +from .types.index_endpoint_service import MutateDeployedIndexRequest +from .types.index_endpoint_service import MutateDeployedIndexResponse from .types.index_endpoint_service import UndeployIndexOperationMetadata from .types.index_endpoint_service import UndeployIndexRequest from .types.index_endpoint_service import UndeployIndexResponse @@ -447,12 +451,14 @@ from .types.training_pipeline import FractionSplit from .types.training_pipeline import InputDataConfig from .types.training_pipeline import PredefinedSplit +from .types.training_pipeline import StratifiedSplit from .types.training_pipeline import TimestampSplit from .types.training_pipeline import TrainingPipeline from .types.types import BoolArray from .types.types import DoubleArray from .types.types import Int64Array from .types.types import StringArray +from .types.unmanaged_container_model import UnmanagedContainerModel from .types.user_action_reference import UserActionReference from .types.value import Value from .types.vizier_service import AddTrialMeasurementRequest @@ -529,6 +535,7 @@ "BatchReadTensorboardTimeSeriesDataResponse", "BigQueryDestination", "BigQuerySource", + "BlurBaselineConfig", "BoolArray", "CancelBatchPredictionJobRequest", "CancelCustomJobRequest", @@ -813,6 +820,9 @@ "ModelMonitoringObjectiveConfig", "ModelMonitoringStatsAnomalies", "ModelServiceClient", + "MutateDeployedIndexOperationMetadata", + "MutateDeployedIndexRequest", + "MutateDeployedIndexResponse", "NearestNeighborSearchOperationMetadata", "PauseModelDeploymentMonitoringJobRequest", "PipelineJob", @@ -866,6 +876,7 @@ "SpecialistPool", "SpecialistPoolServiceClient", "StopTrialRequest", + "StratifiedSplit", "StreamingReadFeatureValuesRequest", "StringArray", "Study", @@ -895,6 +906,7 @@ "UndeployModelOperationMetadata", "UndeployModelRequest", "UndeployModelResponse", + "UnmanagedContainerModel", "UpdateArtifactRequest", "UpdateContextRequest", "UpdateDatasetRequest", diff --git a/google/cloud/aiplatform_v1beta1/gapic_metadata.json b/google/cloud/aiplatform_v1beta1/gapic_metadata.json index d6469e96ee..b584f16b81 100644 --- a/google/cloud/aiplatform_v1beta1/gapic_metadata.json +++ b/google/cloud/aiplatform_v1beta1/gapic_metadata.json @@ -481,6 +481,11 @@ "list_index_endpoints" ] }, + "MutateDeployedIndex": { + "methods": [ + "mutate_deployed_index" + ] + }, "UndeployIndex": { "methods": [ "undeploy_index" @@ -521,6 +526,11 @@ "list_index_endpoints" ] }, + "MutateDeployedIndex": { + "methods": [ + "mutate_deployed_index" + ] + }, "UndeployIndex": { "methods": [ "undeploy_index" diff --git a/google/cloud/aiplatform_v1beta1/services/dataset_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/dataset_service/async_client.py index 55928376eb..b91bb39757 100644 --- a/google/cloud/aiplatform_v1beta1/services/dataset_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/dataset_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/dataset_service/client.py b/google/cloud/aiplatform_v1beta1/services/dataset_service/client.py index ef8f53a778..8f94725a64 100644 --- a/google/cloud/aiplatform_v1beta1/services/dataset_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/dataset_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -359,8 +361,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/base.py index fa3c6d2603..50109d924a 100644 --- a/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/grpc.py index eb5c774d77..6d0916b819 100644 --- a/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/grpc_asyncio.py index 52583b4ac6..2ace47cd68 100644 --- a/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/dataset_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/endpoint_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/endpoint_service/async_client.py index 8d794973c6..9511c58a96 100644 --- a/google/cloud/aiplatform_v1beta1/services/endpoint_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/endpoint_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -188,6 +191,7 @@ async def create_endpoint( *, parent: str = None, endpoint: gca_endpoint.Endpoint = None, + endpoint_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -211,6 +215,21 @@ async def create_endpoint( This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + endpoint_id (:class:`str`): + Immutable. The ID to use for endpoint, which will become + the final component of the endpoint resource name. If + not provided, Vertex AI will generate a value for this + ID. + + This value should be 1-10 characters, and valid + characters are /[0-9]/. When using HTTP/JSON, this field + is populated based on a query string argument, such as + ``?endpoint_id=12345``. This is the fallback for fields + that are not included in either the URI or the body. + + This corresponds to the ``endpoint_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. @@ -228,7 +247,7 @@ async def create_endpoint( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, endpoint]) + has_flattened_params = any([parent, endpoint, endpoint_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -243,6 +262,8 @@ async def create_endpoint( request.parent = parent if endpoint is not None: request.endpoint = endpoint + if endpoint_id is not None: + request.endpoint_id = endpoint_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/aiplatform_v1beta1/services/endpoint_service/client.py b/google/cloud/aiplatform_v1beta1/services/endpoint_service/client.py index 676f4d5de0..247fc94dcd 100644 --- a/google/cloud/aiplatform_v1beta1/services/endpoint_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/endpoint_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -343,8 +345,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -415,6 +424,7 @@ def create_endpoint( *, parent: str = None, endpoint: gca_endpoint.Endpoint = None, + endpoint_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -438,6 +448,21 @@ def create_endpoint( This corresponds to the ``endpoint`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + endpoint_id (str): + Immutable. The ID to use for endpoint, which will become + the final component of the endpoint resource name. If + not provided, Vertex AI will generate a value for this + ID. + + This value should be 1-10 characters, and valid + characters are /[0-9]/. When using HTTP/JSON, this field + is populated based on a query string argument, such as + ``?endpoint_id=12345``. This is the fallback for fields + that are not included in either the URI or the body. + + This corresponds to the ``endpoint_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. @@ -455,7 +480,7 @@ def create_endpoint( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, endpoint]) + has_flattened_params = any([parent, endpoint, endpoint_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -474,6 +499,8 @@ def create_endpoint( request.parent = parent if endpoint is not None: request.endpoint = endpoint + if endpoint_id is not None: + request.endpoint_id = endpoint_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/base.py index e34cabe703..31126b6a54 100644 --- a/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/grpc.py index 0ba6ae6491..8892dff9c5 100644 --- a/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/grpc_asyncio.py index 1b8b1b7a2f..196f7665f3 100644 --- a/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/endpoint_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/async_client.py index 2d7dd457a9..73322758b5 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, AsyncIterable, Awaitable, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.cloud.aiplatform_v1beta1.types import featurestore_online_service from .transports.base import ( diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/client.py b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/client.py index c9417cff0c..079786dd1d 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Iterable, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.cloud.aiplatform_v1beta1.types import featurestore_online_service from .transports.base import ( @@ -298,8 +300,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/base.py index 37334f7bd2..5ecb44843f 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/base.py @@ -18,10 +18,10 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/grpc.py index 2b7e5beccb..68904736ac 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/grpc.py @@ -16,8 +16,8 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/grpc_asyncio.py index 4032cb5115..83a4779a2f 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_online_serving_service/transports/grpc_asyncio.py @@ -16,8 +16,8 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/featurestore_service/async_client.py index 47d7b9b5cc..cbe4cf700b 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -195,6 +198,7 @@ async def create_featurestore( *, parent: str = None, featurestore: gca_featurestore.Featurestore = None, + featurestore_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -219,6 +223,21 @@ async def create_featurestore( This corresponds to the ``featurestore`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + featurestore_id (:class:`str`): + Required. The ID to use for this Featurestore, which + will become the final component of the Featurestore's + resource name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within the project and + location. + + This corresponds to the ``featurestore_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. @@ -229,16 +248,16 @@ async def create_featurestore( google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be - :class:`google.cloud.aiplatform_v1beta1.types.Featurestore` - Featurestore configuration information on how the - Featurestore is configured. + The result type for the operation will be :class:`google.cloud.aiplatform_v1beta1.types.Featurestore` Vertex AI Feature Store provides a centralized repository for organizing, + storing, and serving ML features. The Featurestore is + a top-level container for your features and their + values. """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, featurestore]) + has_flattened_params = any([parent, featurestore, featurestore_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -253,6 +272,8 @@ async def create_featurestore( request.parent = parent if featurestore is not None: request.featurestore = featurestore + if featurestore_id is not None: + request.featurestore_id = featurestore_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -312,9 +333,11 @@ async def get_featurestore( Returns: google.cloud.aiplatform_v1beta1.types.Featurestore: - Featurestore configuration - information on how the Featurestore is - configured. + Vertex AI Feature Store provides a + centralized repository for organizing, + storing, and serving ML features. The + Featurestore is a top-level container + for your features and their values. """ # Create or coerce a protobuf request object. @@ -487,10 +510,10 @@ async def update_featurestore( google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be - :class:`google.cloud.aiplatform_v1beta1.types.Featurestore` - Featurestore configuration information on how the - Featurestore is configured. + The result type for the operation will be :class:`google.cloud.aiplatform_v1beta1.types.Featurestore` Vertex AI Feature Store provides a centralized repository for organizing, + storing, and serving ML features. The Featurestore is + a top-level container for your features and their + values. """ # Create or coerce a protobuf request object. @@ -656,6 +679,7 @@ async def create_entity_type( *, parent: str = None, entity_type: gca_entity_type.EntityType = None, + entity_type_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -679,6 +703,20 @@ async def create_entity_type( This corresponds to the ``entity_type`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + entity_type_id (:class:`str`): + Required. The ID to use for the EntityType, which will + become the final component of the EntityType's resource + name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within a featurestore. + + This corresponds to the ``entity_type_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. @@ -698,7 +736,7 @@ async def create_entity_type( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, entity_type]) + has_flattened_params = any([parent, entity_type, entity_type_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -713,6 +751,8 @@ async def create_entity_type( request.parent = parent if entity_type is not None: request.entity_type = entity_type + if entity_type_id is not None: + request.entity_type_id = entity_type_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -1112,6 +1152,7 @@ async def create_feature( *, parent: str = None, feature: gca_feature.Feature = None, + feature_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -1135,6 +1176,20 @@ async def create_feature( This corresponds to the ``feature`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + feature_id (:class:`str`): + Required. The ID to use for the Feature, which will + become the final component of the Feature's resource + name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within an EntityType. + + This corresponds to the ``feature_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. @@ -1153,7 +1208,7 @@ async def create_feature( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, feature]) + has_flattened_params = any([parent, feature, feature_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -1168,6 +1223,8 @@ async def create_feature( request.parent = parent if feature is not None: request.feature = feature + if feature_id is not None: + request.feature_id = feature_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_service/client.py b/google/cloud/aiplatform_v1beta1/services/featurestore_service/client.py index a4efd0bd74..a149a9c488 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -345,8 +347,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -417,6 +426,7 @@ def create_featurestore( *, parent: str = None, featurestore: gca_featurestore.Featurestore = None, + featurestore_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -441,6 +451,21 @@ def create_featurestore( This corresponds to the ``featurestore`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + featurestore_id (str): + Required. The ID to use for this Featurestore, which + will become the final component of the Featurestore's + resource name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within the project and + location. + + This corresponds to the ``featurestore_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. @@ -451,16 +476,16 @@ def create_featurestore( google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be - :class:`google.cloud.aiplatform_v1beta1.types.Featurestore` - Featurestore configuration information on how the - Featurestore is configured. + The result type for the operation will be :class:`google.cloud.aiplatform_v1beta1.types.Featurestore` Vertex AI Feature Store provides a centralized repository for organizing, + storing, and serving ML features. The Featurestore is + a top-level container for your features and their + values. """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, featurestore]) + has_flattened_params = any([parent, featurestore, featurestore_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -479,6 +504,8 @@ def create_featurestore( request.parent = parent if featurestore is not None: request.featurestore = featurestore + if featurestore_id is not None: + request.featurestore_id = featurestore_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -534,9 +561,11 @@ def get_featurestore( Returns: google.cloud.aiplatform_v1beta1.types.Featurestore: - Featurestore configuration - information on how the Featurestore is - configured. + Vertex AI Feature Store provides a + centralized repository for organizing, + storing, and serving ML features. The + Featurestore is a top-level container + for your features and their values. """ # Create or coerce a protobuf request object. @@ -709,10 +738,10 @@ def update_featurestore( google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be - :class:`google.cloud.aiplatform_v1beta1.types.Featurestore` - Featurestore configuration information on how the - Featurestore is configured. + The result type for the operation will be :class:`google.cloud.aiplatform_v1beta1.types.Featurestore` Vertex AI Feature Store provides a centralized repository for organizing, + storing, and serving ML features. The Featurestore is + a top-level container for your features and their + values. """ # Create or coerce a protobuf request object. @@ -878,6 +907,7 @@ def create_entity_type( *, parent: str = None, entity_type: gca_entity_type.EntityType = None, + entity_type_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -901,6 +931,20 @@ def create_entity_type( This corresponds to the ``entity_type`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + entity_type_id (str): + Required. The ID to use for the EntityType, which will + become the final component of the EntityType's resource + name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within a featurestore. + + This corresponds to the ``entity_type_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. @@ -920,7 +964,7 @@ def create_entity_type( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, entity_type]) + has_flattened_params = any([parent, entity_type, entity_type_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -939,6 +983,8 @@ def create_entity_type( request.parent = parent if entity_type is not None: request.entity_type = entity_type + if entity_type_id is not None: + request.entity_type_id = entity_type_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. @@ -1334,6 +1380,7 @@ def create_feature( *, parent: str = None, feature: gca_feature.Feature = None, + feature_id: str = None, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -1357,6 +1404,20 @@ def create_feature( This corresponds to the ``feature`` field on the ``request`` instance; if ``request`` is provided, this should not be set. + feature_id (str): + Required. The ID to use for the Feature, which will + become the final component of the Feature's resource + name. + + This value may be up to 60 characters, and valid + characters are ``[a-z0-9_]``. The first character cannot + be a number. + + The value must be unique within an EntityType. + + This corresponds to the ``feature_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. @@ -1375,7 +1436,7 @@ def create_feature( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - has_flattened_params = any([parent, feature]) + has_flattened_params = any([parent, feature, feature_id]) if request is not None and has_flattened_params: raise ValueError( "If the `request` argument is set, then none of " @@ -1394,6 +1455,8 @@ def create_feature( request.parent = parent if feature is not None: request.feature = feature + if feature_id is not None: + request.feature_id = feature_id # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/base.py index d9e46fc915..eb86454877 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/grpc.py index c029187a23..02c4ae728c 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/grpc_asyncio.py index 51d56d2c07..56d8879265 100644 --- a/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/featurestore_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/async_client.py index 36705b0b13..a1e5aa81b8 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -795,6 +798,105 @@ async def undeploy_index( # Done; return the response. return response + async def mutate_deployed_index( + self, + request: Union[index_endpoint_service.MutateDeployedIndexRequest, dict] = None, + *, + index_endpoint: str = None, + deployed_index: gca_index_endpoint.DeployedIndex = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Update an existing DeployedIndex under an + IndexEndpoint. + + Args: + request (Union[google.cloud.aiplatform_v1beta1.types.MutateDeployedIndexRequest, dict]): + The request object. Request message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1beta1.IndexEndpointService.MutateDeployedIndex]. + index_endpoint (:class:`str`): + Required. The name of the IndexEndpoint resource into + which to deploy an Index. Format: + ``projects/{project}/locations/{location}/indexEndpoints/{index_endpoint}`` + + This corresponds to the ``index_endpoint`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + deployed_index (:class:`google.cloud.aiplatform_v1beta1.types.DeployedIndex`): + Required. The DeployedIndex to be updated within the + IndexEndpoint. Currently, the updatable fields are + [DeployedIndex][automatic_resources] and + [DeployedIndex][dedicated_resources] + + This corresponds to the ``deployed_index`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.aiplatform_v1beta1.types.MutateDeployedIndexResponse` + Response message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1beta1.IndexEndpointService.MutateDeployedIndex]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([index_endpoint, deployed_index]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = index_endpoint_service.MutateDeployedIndexRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if index_endpoint is not None: + request.index_endpoint = index_endpoint + if deployed_index is not None: + request.deployed_index = deployed_index + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.mutate_deployed_index, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("index_endpoint", request.index_endpoint),) + ), + ) + + # 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, + index_endpoint_service.MutateDeployedIndexResponse, + metadata_type=index_endpoint_service.MutateDeployedIndexOperationMetadata, + ) + + # Done; return the response. + return response + async def __aenter__(self): return self diff --git a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/client.py b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/client.py index e9142cc56e..49f4dc9da6 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -309,8 +311,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -994,6 +1003,105 @@ def undeploy_index( # Done; return the response. return response + def mutate_deployed_index( + self, + request: Union[index_endpoint_service.MutateDeployedIndexRequest, dict] = None, + *, + index_endpoint: str = None, + deployed_index: gca_index_endpoint.DeployedIndex = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gac_operation.Operation: + r"""Update an existing DeployedIndex under an + IndexEndpoint. + + Args: + request (Union[google.cloud.aiplatform_v1beta1.types.MutateDeployedIndexRequest, dict]): + The request object. Request message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1beta1.IndexEndpointService.MutateDeployedIndex]. + index_endpoint (str): + Required. The name of the IndexEndpoint resource into + which to deploy an Index. Format: + ``projects/{project}/locations/{location}/indexEndpoints/{index_endpoint}`` + + This corresponds to the ``index_endpoint`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + deployed_index (google.cloud.aiplatform_v1beta1.types.DeployedIndex): + Required. The DeployedIndex to be updated within the + IndexEndpoint. Currently, the updatable fields are + [DeployedIndex][automatic_resources] and + [DeployedIndex][dedicated_resources] + + This corresponds to the ``deployed_index`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.aiplatform_v1beta1.types.MutateDeployedIndexResponse` + Response message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1beta1.IndexEndpointService.MutateDeployedIndex]. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([index_endpoint, deployed_index]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a index_endpoint_service.MutateDeployedIndexRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, index_endpoint_service.MutateDeployedIndexRequest): + request = index_endpoint_service.MutateDeployedIndexRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if index_endpoint is not None: + request.index_endpoint = index_endpoint + if deployed_index is not None: + request.deployed_index = deployed_index + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_deployed_index] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("index_endpoint", request.index_endpoint),) + ), + ) + + # Send the request. + response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,) + + # Wrap the response in an operation future. + response = gac_operation.from_gapic( + response, + self._transport.operations_client, + index_endpoint_service.MutateDeployedIndexResponse, + metadata_type=index_endpoint_service.MutateDeployedIndexOperationMetadata, + ) + + # Done; return the response. + return response + def __enter__(self): return self diff --git a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/base.py index c220dba926..729e32879b 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore @@ -152,6 +152,11 @@ def _prep_wrapped_messages(self, client_info): self.undeploy_index: gapic_v1.method.wrap_method( self.undeploy_index, default_timeout=5.0, client_info=client_info, ), + self.mutate_deployed_index: gapic_v1.method.wrap_method( + self.mutate_deployed_index, + default_timeout=None, + client_info=client_info, + ), } def close(self): @@ -237,5 +242,14 @@ def undeploy_index( ]: raise NotImplementedError() + @property + def mutate_deployed_index( + self, + ) -> Callable[ + [index_endpoint_service.MutateDeployedIndexRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + __all__ = ("IndexEndpointServiceTransport",) diff --git a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/grpc.py index b7523c1ece..5704bc41f4 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -446,6 +446,35 @@ def undeploy_index( ) return self._stubs["undeploy_index"] + @property + def mutate_deployed_index( + self, + ) -> Callable[ + [index_endpoint_service.MutateDeployedIndexRequest], operations_pb2.Operation + ]: + r"""Return a callable for the mutate deployed index method over gRPC. + + Update an existing DeployedIndex under an + IndexEndpoint. + + Returns: + Callable[[~.MutateDeployedIndexRequest], + ~.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 "mutate_deployed_index" not in self._stubs: + self._stubs["mutate_deployed_index"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1beta1.IndexEndpointService/MutateDeployedIndex", + request_serializer=index_endpoint_service.MutateDeployedIndexRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["mutate_deployed_index"] + def close(self): self.grpc_channel.close() diff --git a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/grpc_asyncio.py index 49cae08edb..e8b2c2ccaf 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/index_endpoint_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -454,6 +454,36 @@ def undeploy_index( ) return self._stubs["undeploy_index"] + @property + def mutate_deployed_index( + self, + ) -> Callable[ + [index_endpoint_service.MutateDeployedIndexRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the mutate deployed index method over gRPC. + + Update an existing DeployedIndex under an + IndexEndpoint. + + Returns: + Callable[[~.MutateDeployedIndexRequest], + 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 "mutate_deployed_index" not in self._stubs: + self._stubs["mutate_deployed_index"] = self.grpc_channel.unary_unary( + "/google.cloud.aiplatform.v1beta1.IndexEndpointService/MutateDeployedIndex", + request_serializer=index_endpoint_service.MutateDeployedIndexRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["mutate_deployed_index"] + def close(self): return self.grpc_channel.close() diff --git a/google/cloud/aiplatform_v1beta1/services/index_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/index_service/async_client.py index 72a479145d..0838cdde22 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/index_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/index_service/client.py b/google/cloud/aiplatform_v1beta1/services/index_service/client.py index 3c9f14ab8d..57a05df255 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/index_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -309,8 +311,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1beta1/services/index_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/index_service/transports/base.py index 29ad18043e..cfb9266121 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/index_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/index_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/index_service/transports/grpc.py index 1c1d6cb72d..8173064eaf 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/index_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/index_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/index_service/transports/grpc_asyncio.py index 2fa140d53c..af440edd6d 100644 --- a/google/cloud/aiplatform_v1beta1/services/index_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/index_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/job_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/job_service/async_client.py index e989970f3c..6022a7c16a 100644 --- a/google/cloud/aiplatform_v1beta1/services/job_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/job_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -60,6 +63,7 @@ from google.cloud.aiplatform_v1beta1.types import model_monitoring from google.cloud.aiplatform_v1beta1.types import operation as gca_operation from google.cloud.aiplatform_v1beta1.types import study +from google.cloud.aiplatform_v1beta1.types import unmanaged_container_model from google.protobuf import duration_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore @@ -1973,7 +1977,7 @@ async def search_model_deployment_monitoring_stats_anomalies( should not be set. deployed_model_id (:class:`str`): Required. The DeployedModel ID of the - [google.cloud.aiplatform.master.ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. + [ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. This corresponds to the ``deployed_model_id`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/google/cloud/aiplatform_v1beta1/services/job_service/client.py b/google/cloud/aiplatform_v1beta1/services/job_service/client.py index c3757eab50..57d840f33e 100644 --- a/google/cloud/aiplatform_v1beta1/services/job_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/job_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -64,6 +66,7 @@ from google.cloud.aiplatform_v1beta1.types import model_monitoring from google.cloud.aiplatform_v1beta1.types import operation as gca_operation from google.cloud.aiplatform_v1beta1.types import study +from google.cloud.aiplatform_v1beta1.types import unmanaged_container_model from google.protobuf import duration_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore @@ -491,8 +494,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -2328,7 +2338,7 @@ def search_model_deployment_monitoring_stats_anomalies( should not be set. deployed_model_id (str): Required. The DeployedModel ID of the - [google.cloud.aiplatform.master.ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. + [ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. This corresponds to the ``deployed_model_id`` field on the ``request`` instance; if ``request`` is provided, this diff --git a/google/cloud/aiplatform_v1beta1/services/job_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/job_service/transports/base.py index 3d26f6ea89..75f1226267 100644 --- a/google/cloud/aiplatform_v1beta1/services/job_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/job_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/job_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/job_service/transports/grpc.py index 83876c1222..baaa922a45 100644 --- a/google/cloud/aiplatform_v1beta1/services/job_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/job_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/job_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/job_service/transports/grpc_asyncio.py index 32df422c81..02c6188be4 100644 --- a/google/cloud/aiplatform_v1beta1/services/job_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/job_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/metadata_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/metadata_service/async_client.py index 3ec9863269..e58591c541 100644 --- a/google/cloud/aiplatform_v1beta1/services/metadata_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/metadata_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/metadata_service/client.py b/google/cloud/aiplatform_v1beta1/services/metadata_service/client.py index d251b779d1..d0f873ad9e 100644 --- a/google/cloud/aiplatform_v1beta1/services/metadata_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/metadata_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -387,8 +389,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/base.py index 7ebb35934e..d2ceb126be 100644 --- a/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/grpc.py index 0681f862f4..2ec4b66c37 100644 --- a/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/grpc_asyncio.py index 16b6dc2a73..d990fbbdad 100644 --- a/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/metadata_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/migration_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/migration_service/async_client.py index 0f82d0f527..d16eea5d41 100644 --- a/google/cloud/aiplatform_v1beta1/services/migration_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/migration_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/migration_service/client.py b/google/cloud/aiplatform_v1beta1/services/migration_service/client.py index 4491969274..5463d3db1c 100644 --- a/google/cloud/aiplatform_v1beta1/services/migration_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/migration_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore @@ -383,8 +385,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1beta1/services/migration_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/migration_service/transports/base.py index 3552e52e1b..5557f97a46 100644 --- a/google/cloud/aiplatform_v1beta1/services/migration_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/migration_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/migration_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/migration_service/transports/grpc.py index 1c040ce74e..1c2935c97c 100644 --- a/google/cloud/aiplatform_v1beta1/services/migration_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/migration_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/migration_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/migration_service/transports/grpc_asyncio.py index c12010733b..a5f5e33a8b 100644 --- a/google/cloud/aiplatform_v1beta1/services/migration_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/migration_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/model_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/model_service/async_client.py index 097a7dac64..028e8bb41a 100644 --- a/google/cloud/aiplatform_v1beta1/services/model_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/model_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -525,8 +528,13 @@ async def delete_model( ) -> operation_async.AsyncOperation: r"""Deletes a Model. - Model can only be deleted if there are no [DeployedModels][] - created from it. + A model cannot be deleted if any + [Endpoint][google.cloud.aiplatform.v1beta1.Endpoint] resource + has a + [DeployedModel][google.cloud.aiplatform.v1beta1.DeployedModel] + based on the model in its + [deployed_models][google.cloud.aiplatform.v1beta1.Endpoint.deployed_models] + field. Args: request (Union[google.cloud.aiplatform_v1beta1.types.DeleteModelRequest, dict]): @@ -620,7 +628,7 @@ async def export_model( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: - r"""Exports a trained, exportable, Model to a location specified by + r"""Exports a trained, exportable Model to a location specified by the user. A Model is considered to be exportable if it has at least one [supported export format][google.cloud.aiplatform.v1beta1.Model.supported_export_formats]. diff --git a/google/cloud/aiplatform_v1beta1/services/model_service/client.py b/google/cloud/aiplatform_v1beta1/services/model_service/client.py index 800dd3d64f..1ab512337a 100644 --- a/google/cloud/aiplatform_v1beta1/services/model_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/model_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -369,8 +371,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -771,8 +780,13 @@ def delete_model( ) -> gac_operation.Operation: r"""Deletes a Model. - Model can only be deleted if there are no [DeployedModels][] - created from it. + A model cannot be deleted if any + [Endpoint][google.cloud.aiplatform.v1beta1.Endpoint] resource + has a + [DeployedModel][google.cloud.aiplatform.v1beta1.DeployedModel] + based on the model in its + [deployed_models][google.cloud.aiplatform.v1beta1.Endpoint.deployed_models] + field. Args: request (Union[google.cloud.aiplatform_v1beta1.types.DeleteModelRequest, dict]): @@ -866,7 +880,7 @@ def export_model( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> gac_operation.Operation: - r"""Exports a trained, exportable, Model to a location specified by + r"""Exports a trained, exportable Model to a location specified by the user. A Model is considered to be exportable if it has at least one [supported export format][google.cloud.aiplatform.v1beta1.Model.supported_export_formats]. diff --git a/google/cloud/aiplatform_v1beta1/services/model_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/model_service/transports/base.py index 1bbcceec8e..fa0da90bf0 100644 --- a/google/cloud/aiplatform_v1beta1/services/model_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/model_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/model_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/model_service/transports/grpc.py index 83ef737b5c..4e4d32fe03 100644 --- a/google/cloud/aiplatform_v1beta1/services/model_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/model_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -356,8 +356,13 @@ def delete_model( Deletes a Model. - Model can only be deleted if there are no [DeployedModels][] - created from it. + A model cannot be deleted if any + [Endpoint][google.cloud.aiplatform.v1beta1.Endpoint] resource + has a + [DeployedModel][google.cloud.aiplatform.v1beta1.DeployedModel] + based on the model in its + [deployed_models][google.cloud.aiplatform.v1beta1.Endpoint.deployed_models] + field. Returns: Callable[[~.DeleteModelRequest], @@ -383,7 +388,7 @@ def export_model( ) -> Callable[[model_service.ExportModelRequest], operations_pb2.Operation]: r"""Return a callable for the export model method over gRPC. - Exports a trained, exportable, Model to a location specified by + Exports a trained, exportable Model to a location specified by the user. A Model is considered to be exportable if it has at least one [supported export format][google.cloud.aiplatform.v1beta1.Model.supported_export_formats]. diff --git a/google/cloud/aiplatform_v1beta1/services/model_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/model_service/transports/grpc_asyncio.py index d24d4df843..f3fa67b56d 100644 --- a/google/cloud/aiplatform_v1beta1/services/model_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/model_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -368,8 +368,13 @@ def delete_model( Deletes a Model. - Model can only be deleted if there are no [DeployedModels][] - created from it. + A model cannot be deleted if any + [Endpoint][google.cloud.aiplatform.v1beta1.Endpoint] resource + has a + [DeployedModel][google.cloud.aiplatform.v1beta1.DeployedModel] + based on the model in its + [deployed_models][google.cloud.aiplatform.v1beta1.Endpoint.deployed_models] + field. Returns: Callable[[~.DeleteModelRequest], @@ -397,7 +402,7 @@ def export_model( ]: r"""Return a callable for the export model method over gRPC. - Exports a trained, exportable, Model to a location specified by + Exports a trained, exportable Model to a location specified by the user. A Model is considered to be exportable if it has at least one [supported export format][google.cloud.aiplatform.v1beta1.Model.supported_export_formats]. diff --git a/google/cloud/aiplatform_v1beta1/services/pipeline_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/pipeline_service/async_client.py index b32a1fe93f..c31048b9eb 100644 --- a/google/cloud/aiplatform_v1beta1/services/pipeline_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/pipeline_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -54,7 +57,7 @@ class PipelineServiceAsyncClient: """A service for creating and managing Vertex AI's pipelines. This includes both ``TrainingPipeline`` resources (used for AutoML and - custom training) and ``PipelineJob`` resources (used for Vertex + custom training) and ``PipelineJob`` resources (used for Vertex AI Pipelines). """ diff --git a/google/cloud/aiplatform_v1beta1/services/pipeline_service/client.py b/google/cloud/aiplatform_v1beta1/services/pipeline_service/client.py index 02c58d977e..35c2ffab76 100644 --- a/google/cloud/aiplatform_v1beta1/services/pipeline_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/pipeline_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -91,7 +93,7 @@ def get_transport_class(cls, label: str = None,) -> Type[PipelineServiceTranspor class PipelineServiceClient(metaclass=PipelineServiceClientMeta): """A service for creating and managing Vertex AI's pipelines. This includes both ``TrainingPipeline`` resources (used for AutoML and - custom training) and ``PipelineJob`` resources (used for Vertex + custom training) and ``PipelineJob`` resources (used for Vertex AI Pipelines). """ @@ -447,8 +449,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/base.py index 044cb8de6e..3c1512e2cd 100644 --- a/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/grpc.py index a4b20fa42a..372e193e47 100644 --- a/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -42,7 +42,7 @@ class PipelineServiceGrpcTransport(PipelineServiceTransport): A service for creating and managing Vertex AI's pipelines. This includes both ``TrainingPipeline`` resources (used for AutoML and - custom training) and ``PipelineJob`` resources (used for Vertex + custom training) and ``PipelineJob`` resources (used for Vertex AI Pipelines). This class defines the same methods as the primary client, so the diff --git a/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/grpc_asyncio.py index d4ce5a4007..d5c7e82b30 100644 --- a/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/pipeline_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -43,7 +43,7 @@ class PipelineServiceGrpcAsyncIOTransport(PipelineServiceTransport): A service for creating and managing Vertex AI's pipelines. This includes both ``TrainingPipeline`` resources (used for AutoML and - custom training) and ``PipelineJob`` resources (used for Vertex + custom training) and ``PipelineJob`` resources (used for Vertex AI Pipelines). This class defines the same methods as the primary client, so the diff --git a/google/cloud/aiplatform_v1beta1/services/prediction_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/prediction_service/async_client.py index 16e531faf8..fd0677b922 100644 --- a/google/cloud/aiplatform_v1beta1/services/prediction_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/prediction_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api import httpbody_pb2 # type: ignore from google.cloud.aiplatform_v1beta1.types import explanation @@ -283,8 +286,17 @@ async def raw_predict( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> httpbody_pb2.HttpBody: - r"""Perform an online prediction with arbitrary http - payload. + r"""Perform an online prediction with an arbitrary HTTP payload. + + The response includes the following HTTP headers: + + - ``X-Vertex-AI-Endpoint-Id``: ID of the + [Endpoint][google.cloud.aiplatform.v1beta1.Endpoint] that + served this prediction. + + - ``X-Vertex-AI-Deployed-Model-Id``: ID of the Endpoint's + [DeployedModel][google.cloud.aiplatform.v1beta1.DeployedModel] + that served this prediction. Args: request (Union[google.cloud.aiplatform_v1beta1.types.RawPredictRequest, dict]): diff --git a/google/cloud/aiplatform_v1beta1/services/prediction_service/client.py b/google/cloud/aiplatform_v1beta1/services/prediction_service/client.py index fdd42b6690..020817c986 100644 --- a/google/cloud/aiplatform_v1beta1/services/prediction_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/prediction_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api import httpbody_pb2 # type: ignore from google.cloud.aiplatform_v1beta1.types import explanation @@ -304,8 +306,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -485,8 +494,17 @@ def raw_predict( timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> httpbody_pb2.HttpBody: - r"""Perform an online prediction with arbitrary http - payload. + r"""Perform an online prediction with an arbitrary HTTP payload. + + The response includes the following HTTP headers: + + - ``X-Vertex-AI-Endpoint-Id``: ID of the + [Endpoint][google.cloud.aiplatform.v1beta1.Endpoint] that + served this prediction. + + - ``X-Vertex-AI-Deployed-Model-Id``: ID of the Endpoint's + [DeployedModel][google.cloud.aiplatform.v1beta1.DeployedModel] + that served this prediction. Args: request (Union[google.cloud.aiplatform_v1beta1.types.RawPredictRequest, dict]): diff --git a/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/base.py index 396d29f5f9..8ea55559e6 100644 --- a/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/base.py @@ -18,10 +18,10 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/grpc.py index fbb8197266..e911abba1e 100644 --- a/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/grpc.py @@ -16,8 +16,8 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -260,8 +260,17 @@ def raw_predict( ) -> Callable[[prediction_service.RawPredictRequest], httpbody_pb2.HttpBody]: r"""Return a callable for the raw predict method over gRPC. - Perform an online prediction with arbitrary http - payload. + Perform an online prediction with an arbitrary HTTP payload. + + The response includes the following HTTP headers: + + - ``X-Vertex-AI-Endpoint-Id``: ID of the + [Endpoint][google.cloud.aiplatform.v1beta1.Endpoint] that + served this prediction. + + - ``X-Vertex-AI-Deployed-Model-Id``: ID of the Endpoint's + [DeployedModel][google.cloud.aiplatform.v1beta1.DeployedModel] + that served this prediction. Returns: Callable[[~.RawPredictRequest], diff --git a/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/grpc_asyncio.py index dfe6cb4c83..4c288670dc 100644 --- a/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/prediction_service/transports/grpc_asyncio.py @@ -16,8 +16,8 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -265,8 +265,17 @@ def raw_predict( ]: r"""Return a callable for the raw predict method over gRPC. - Perform an online prediction with arbitrary http - payload. + Perform an online prediction with an arbitrary HTTP payload. + + The response includes the following HTTP headers: + + - ``X-Vertex-AI-Endpoint-Id``: ID of the + [Endpoint][google.cloud.aiplatform.v1beta1.Endpoint] that + served this prediction. + + - ``X-Vertex-AI-Deployed-Model-Id``: ID of the Endpoint's + [DeployedModel][google.cloud.aiplatform.v1beta1.DeployedModel] + that served this prediction. Returns: Callable[[~.RawPredictRequest], diff --git a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/async_client.py index e5d9a3551e..9d71b5eca5 100644 --- a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/client.py b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/client.py index 4ca026222e..965b05b82b 100644 --- a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -298,8 +300,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/base.py index 2fc46ff661..521dade561 100644 --- a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/grpc.py index d32117f5d7..6676da5865 100644 --- a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/grpc_asyncio.py index 599da0327c..83469e9cbc 100644 --- a/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/specialist_pool_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/async_client.py index ff44f2eedc..605fca1a77 100644 --- a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, AsyncIterable, Awaitable, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/client.py b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/client.py index bb0228d776..81fa3a6665 100644 --- a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Iterable, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore @@ -376,8 +378,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None diff --git a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/base.py index 8b4a5729f6..96c05a9bcc 100644 --- a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/grpc.py index 1cc7696f56..f01df1056a 100644 --- a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/grpc_asyncio.py index a6049c14b0..6a913aee88 100644 --- a/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/tensorboard_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/vizier_service/async_client.py b/google/cloud/aiplatform_v1beta1/services/vizier_service/async_client.py index 112499c7e8..9ba5f46b14 100644 --- a/google/cloud/aiplatform_v1beta1/services/vizier_service/async_client.py +++ b/google/cloud/aiplatform_v1beta1/services/vizier_service/async_client.py @@ -19,14 +19,17 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core.client_options import ClientOptions # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore @@ -41,8 +44,8 @@ class VizierServiceAsyncClient: - """Vertex Vizier API. - Vizier service is a GCP service to solve blackbox optimization + """Vertex AI Vizier API. + Vertex AI Vizier is a service to solve blackbox optimization problems, such as tuning machine learning hyperparameters and searching over deep learning architectures. """ @@ -216,7 +219,9 @@ async def create_study( Returns: google.cloud.aiplatform_v1beta1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -287,7 +292,9 @@ async def get_study( Returns: google.cloud.aiplatform_v1beta1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -505,7 +512,9 @@ async def lookup_study( Returns: google.cloud.aiplatform_v1beta1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -553,7 +562,7 @@ async def suggest_trials( metadata: Sequence[Tuple[str, str]] = (), ) -> operation_async.AsyncOperation: r"""Adds one or more Trials to a Study, with parameter values - suggested by Vertex Vizier. Returns a long-running operation + suggested by Vertex AI Vizier. Returns a long-running operation associated with the generation of Trial suggestions. When this long-running operation succeeds, it will contain a [SuggestTrialsResponse][google.cloud.ml.v1.SuggestTrialsResponse]. diff --git a/google/cloud/aiplatform_v1beta1/services/vizier_service/client.py b/google/cloud/aiplatform_v1beta1/services/vizier_service/client.py index 282c0013af..94f0134400 100644 --- a/google/cloud/aiplatform_v1beta1/services/vizier_service/client.py +++ b/google/cloud/aiplatform_v1beta1/services/vizier_service/client.py @@ -14,23 +14,25 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore -OptionalRetry = Union[retries.Retry, object] +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore @@ -76,8 +78,8 @@ def get_transport_class(cls, label: str = None,) -> Type[VizierServiceTransport] class VizierServiceClient(metaclass=VizierServiceClientMeta): - """Vertex Vizier API. - Vizier service is a GCP service to solve blackbox optimization + """Vertex AI Vizier API. + Vertex AI Vizier is a service to solve blackbox optimization problems, such as tuning machine learning hyperparameters and searching over deep learning architectures. """ @@ -322,8 +324,15 @@ def __init__( client_options = client_options_lib.ClientOptions() # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + if os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") not in ( + "true", + "false", + ): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + use_client_cert = ( + os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true" ) client_cert_source_func = None @@ -428,7 +437,9 @@ def create_study( Returns: google.cloud.aiplatform_v1beta1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -499,7 +510,9 @@ def get_study( Returns: google.cloud.aiplatform_v1beta1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -717,7 +730,9 @@ def lookup_study( Returns: google.cloud.aiplatform_v1beta1.types.Study: + LINT.IfChange A message representing a Study. + """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have @@ -765,7 +780,7 @@ def suggest_trials( metadata: Sequence[Tuple[str, str]] = (), ) -> operation.Operation: r"""Adds one or more Trials to a Study, with parameter values - suggested by Vertex Vizier. Returns a long-running operation + suggested by Vertex AI Vizier. Returns a long-running operation associated with the generation of Trial suggestions. When this long-running operation succeeds, it will contain a [SuggestTrialsResponse][google.cloud.ml.v1.SuggestTrialsResponse]. diff --git a/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/base.py b/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/base.py index 03b79e6643..f52d925d28 100644 --- a/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/base.py +++ b/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/base.py @@ -18,11 +18,11 @@ import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore -from google.api_core import operations_v1 # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore diff --git a/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/grpc.py b/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/grpc.py index d8a4a3ec89..5cf7cbaee1 100644 --- a/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/grpc.py +++ b/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/grpc.py @@ -16,9 +16,9 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import operations_v1 # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -36,8 +36,8 @@ class VizierServiceGrpcTransport(VizierServiceTransport): """gRPC backend transport for VizierService. - Vertex Vizier API. - Vizier service is a GCP service to solve blackbox optimization + Vertex AI Vizier API. + Vertex AI Vizier is a service to solve blackbox optimization problems, such as tuning machine learning hyperparameters and searching over deep learning architectures. @@ -388,7 +388,7 @@ def suggest_trials( r"""Return a callable for the suggest trials method over gRPC. Adds one or more Trials to a Study, with parameter values - suggested by Vertex Vizier. Returns a long-running operation + suggested by Vertex AI Vizier. Returns a long-running operation associated with the generation of Trial suggestions. When this long-running operation succeeds, it will contain a [SuggestTrialsResponse][google.cloud.ml.v1.SuggestTrialsResponse]. diff --git a/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/grpc_asyncio.py b/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/grpc_asyncio.py index 012c6339fd..7fdb740e87 100644 --- a/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/grpc_asyncio.py +++ b/google/cloud/aiplatform_v1beta1/services/vizier_service/transports/grpc_asyncio.py @@ -16,9 +16,9 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore -from google.api_core import operations_v1 # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -37,8 +37,8 @@ class VizierServiceGrpcAsyncIOTransport(VizierServiceTransport): """gRPC AsyncIO backend transport for VizierService. - Vertex Vizier API. - Vizier service is a GCP service to solve blackbox optimization + Vertex AI Vizier API. + Vertex AI Vizier is a service to solve blackbox optimization problems, such as tuning machine learning hyperparameters and searching over deep learning architectures. @@ -397,7 +397,7 @@ def suggest_trials( r"""Return a callable for the suggest trials method over gRPC. Adds one or more Trials to a Study, with parameter values - suggested by Vertex Vizier. Returns a long-running operation + suggested by Vertex AI Vizier. Returns a long-running operation associated with the generation of Trial suggestions. When this long-running operation succeeds, it will contain a [SuggestTrialsResponse][google.cloud.ml.v1.SuggestTrialsResponse]. diff --git a/google/cloud/aiplatform_v1beta1/types/__init__.py b/google/cloud/aiplatform_v1beta1/types/__init__.py index b5ce0f36fd..fcd3ca5a42 100644 --- a/google/cloud/aiplatform_v1beta1/types/__init__.py +++ b/google/cloud/aiplatform_v1beta1/types/__init__.py @@ -88,6 +88,7 @@ from .execution import Execution from .explanation import ( Attribution, + BlurBaselineConfig, Explanation, ExplanationMetadataOverride, ExplanationParameters, @@ -175,6 +176,9 @@ GetIndexEndpointRequest, ListIndexEndpointsRequest, ListIndexEndpointsResponse, + MutateDeployedIndexOperationMetadata, + MutateDeployedIndexRequest, + MutateDeployedIndexResponse, UndeployIndexOperationMetadata, UndeployIndexRequest, UndeployIndexResponse, @@ -461,6 +465,7 @@ FractionSplit, InputDataConfig, PredefinedSplit, + StratifiedSplit, TimestampSplit, TrainingPipeline, ) @@ -470,6 +475,7 @@ Int64Array, StringArray, ) +from .unmanaged_container_model import UnmanagedContainerModel from .user_action_reference import UserActionReference from .value import Value from .vizier_service import ( @@ -561,6 +567,7 @@ "Event", "Execution", "Attribution", + "BlurBaselineConfig", "Explanation", "ExplanationMetadataOverride", "ExplanationParameters", @@ -638,6 +645,9 @@ "GetIndexEndpointRequest", "ListIndexEndpointsRequest", "ListIndexEndpointsResponse", + "MutateDeployedIndexOperationMetadata", + "MutateDeployedIndexRequest", + "MutateDeployedIndexResponse", "UndeployIndexOperationMetadata", "UndeployIndexRequest", "UndeployIndexResponse", @@ -888,12 +898,14 @@ "FractionSplit", "InputDataConfig", "PredefinedSplit", + "StratifiedSplit", "TimestampSplit", "TrainingPipeline", "BoolArray", "DoubleArray", "Int64Array", "StringArray", + "UnmanagedContainerModel", "UserActionReference", "Value", "AddTrialMeasurementRequest", diff --git a/google/cloud/aiplatform_v1beta1/types/artifact.py b/google/cloud/aiplatform_v1beta1/types/artifact.py index 31657f0f31..d70d6ace76 100644 --- a/google/cloud/aiplatform_v1beta1/types/artifact.py +++ b/google/cloud/aiplatform_v1beta1/types/artifact.py @@ -62,9 +62,9 @@ class Artifact(proto.Message): The state of this Artifact. This is a property of the Artifact, and does not imply or capture any ongoing process. This property is - managed by clients (such as Vertex Pipelines), - and the system does not prescribe or check the - validity of state transitions. + managed by clients (such as Vertex AI + Pipelines), and the system does not prescribe or + check the validity of state transitions. schema_title (str): The title of the schema describing the metadata. diff --git a/google/cloud/aiplatform_v1beta1/types/batch_prediction_job.py b/google/cloud/aiplatform_v1beta1/types/batch_prediction_job.py index 0353c524b3..80829d444e 100644 --- a/google/cloud/aiplatform_v1beta1/types/batch_prediction_job.py +++ b/google/cloud/aiplatform_v1beta1/types/batch_prediction_job.py @@ -26,6 +26,9 @@ from google.cloud.aiplatform_v1beta1.types import ( manual_batch_tuning_parameters as gca_manual_batch_tuning_parameters, ) +from google.cloud.aiplatform_v1beta1.types import ( + unmanaged_container_model as gca_unmanaged_container_model, +) from google.protobuf import struct_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore @@ -53,11 +56,16 @@ class BatchPredictionJob(proto.Message): Required. The user-defined name of this BatchPredictionJob. model (str): - Required. The name of the Model that produces - the predictions via this job, must share the - same ancestor Location. Starting this job has no - impact on any existing deployments of the Model - and their resources. + The name of the Model resoure that produces the predictions + via this job, must share the same ancestor Location. + Starting this job has no impact on any existing deployments + of the Model and their resources. Exactly one of model and + unmanaged_container_model must be set. + unmanaged_container_model (google.cloud.aiplatform_v1beta1.types.UnmanagedContainerModel): + Contains model information necessary to perform batch + prediction without requiring uploading to model registry. + Exactly one of model and unmanaged_container_model must be + set. input_config (google.cloud.aiplatform_v1beta1.types.BatchPredictionJob.InputConfig): Required. Input configuration of the instances on which predictions are performed. The schema of any single instance @@ -207,6 +215,7 @@ class InputConfig(proto.Message): gcs_source (google.cloud.aiplatform_v1beta1.types.GcsSource): The Cloud Storage location for the input instances. + This field is a member of `oneof`_ ``source``. bigquery_source (google.cloud.aiplatform_v1beta1.types.BigQuerySource): The BigQuery location of the input table. @@ -215,6 +224,7 @@ class InputConfig(proto.Message): if one is provided. The table may contain additional columns that are not described by the schema, and they will be ignored. + This field is a member of `oneof`_ ``source``. instances_format (str): Required. The format in which instances are given, must be @@ -274,6 +284,7 @@ class OutputConfig(proto.Message): per their schema, followed by an additional ``error`` field which as value has [google.rpc.Status][google.rpc.Status] containing only ``code`` and ``message`` fields. + This field is a member of `oneof`_ ``destination``. bigquery_destination (google.cloud.aiplatform_v1beta1.types.BigQueryDestination): The BigQuery project or dataset location where the output is @@ -297,6 +308,7 @@ class OutputConfig(proto.Message): followed by a single "errors" column, which as values has [google.rpc.Status][google.rpc.Status] represented as a STRUCT, and containing only ``code`` and ``message``. + This field is a member of `oneof`_ ``destination``. predictions_format (str): Required. The format in which Vertex AI gives the @@ -332,11 +344,13 @@ class OutputInfo(proto.Message): Output only. The full path of the Cloud Storage directory created, into which the prediction output is written. + This field is a member of `oneof`_ ``output_location``. bigquery_output_dataset (str): Output only. The path of the BigQuery dataset created, in ``bq://projectId.bqDatasetId`` format, into which the prediction output is written. + This field is a member of `oneof`_ ``output_location``. bigquery_output_table (str): Output only. The name of the BigQuery table created, in @@ -356,6 +370,11 @@ class OutputInfo(proto.Message): name = proto.Field(proto.STRING, number=1,) display_name = proto.Field(proto.STRING, number=2,) model = proto.Field(proto.STRING, number=3,) + unmanaged_container_model = proto.Field( + proto.MESSAGE, + number=28, + message=gca_unmanaged_container_model.UnmanagedContainerModel, + ) input_config = proto.Field(proto.MESSAGE, number=4, message=InputConfig,) model_parameters = proto.Field(proto.MESSAGE, number=5, message=struct_pb2.Value,) output_config = proto.Field(proto.MESSAGE, number=6, message=OutputConfig,) diff --git a/google/cloud/aiplatform_v1beta1/types/custom_job.py b/google/cloud/aiplatform_v1beta1/types/custom_job.py index 71c5dc6efa..7ec2a92c03 100644 --- a/google/cloud/aiplatform_v1beta1/types/custom_job.py +++ b/google/cloud/aiplatform_v1beta1/types/custom_job.py @@ -147,9 +147,12 @@ class CustomJobSpec(proto.Message): {project} is a project number, as in ``12345``, and {network} is a network name. - Private services access must already be configured for the - network. If left unspecified, the job is not peered with any - network. + To specify this field, you must have already `configured VPC + Network Peering for Vertex + AI `__. + + If this field is left unspecified, the job is not peered + with any network. base_output_directory (google.cloud.aiplatform_v1beta1.types.GcsDestination): The Cloud Storage location to store the output of this CustomJob or HyperparameterTuningJob. For @@ -224,9 +227,11 @@ class WorkerPoolSpec(proto.Message): Attributes: container_spec (google.cloud.aiplatform_v1beta1.types.ContainerSpec): The custom container task. + This field is a member of `oneof`_ ``task``. python_package_spec (google.cloud.aiplatform_v1beta1.types.PythonPackageSpec): The Python packaged task. + This field is a member of `oneof`_ ``task``. machine_spec (google.cloud.aiplatform_v1beta1.types.MachineSpec): Optional. Immutable. The specification of a diff --git a/google/cloud/aiplatform_v1beta1/types/data_labeling_job.py b/google/cloud/aiplatform_v1beta1/types/data_labeling_job.py index d89f792325..c510216e34 100644 --- a/google/cloud/aiplatform_v1beta1/types/data_labeling_job.py +++ b/google/cloud/aiplatform_v1beta1/types/data_labeling_job.py @@ -179,10 +179,12 @@ class ActiveLearningConfig(proto.Message): Attributes: max_data_item_count (int): Max number of human labeled DataItems. + This field is a member of `oneof`_ ``human_labeling_budget``. max_data_item_percentage (int): Max percent of total DataItems for human labeling. + This field is a member of `oneof`_ ``human_labeling_budget``. sample_config (google.cloud.aiplatform_v1beta1.types.SampleConfig): Active learning data sampling config. For @@ -219,11 +221,13 @@ class SampleConfig(proto.Message): initial_batch_sample_percentage (int): The percentage of data needed to be labeled in the first batch. + This field is a member of `oneof`_ ``initial_batch_sample_size``. following_batch_sample_percentage (int): The percentage of data needed to be labeled in each following batch (except the first batch). + This field is a member of `oneof`_ ``following_batch_sample_size``. sample_strategy (google.cloud.aiplatform_v1beta1.types.SampleConfig.SampleStrategy): Field to choose sampling strategy. Sampling diff --git a/google/cloud/aiplatform_v1beta1/types/dataset.py b/google/cloud/aiplatform_v1beta1/types/dataset.py index 420cca48aa..1a3fc4fe8b 100644 --- a/google/cloud/aiplatform_v1beta1/types/dataset.py +++ b/google/cloud/aiplatform_v1beta1/types/dataset.py @@ -113,6 +113,7 @@ class ImportDataConfig(proto.Message): gcs_source (google.cloud.aiplatform_v1beta1.types.GcsSource): The Google Cloud Storage location for the input content. + This field is a member of `oneof`_ ``source``. data_item_labels (Sequence[google.cloud.aiplatform_v1beta1.types.ImportDataConfig.DataItemLabelsEntry]): Labels that will be applied to newly imported DataItems. If @@ -164,6 +165,7 @@ class ExportDataConfig(proto.Message): with the corresponding annotations' schema title. Inside these sub directories, a schema.yaml will be created to describe the output format. + This field is a member of `oneof`_ ``destination``. annotations_filter (str): A filter on Annotations of the Dataset. Only Annotations on diff --git a/google/cloud/aiplatform_v1beta1/types/endpoint.py b/google/cloud/aiplatform_v1beta1/types/endpoint.py index 9026518f84..4e6981e44e 100644 --- a/google/cloud/aiplatform_v1beta1/types/endpoint.py +++ b/google/cloud/aiplatform_v1beta1/types/endpoint.py @@ -85,17 +85,31 @@ class Endpoint(proto.Message): this key. network (str): The full name of the Google Compute Engine - `network `__ + `network `__ to which the Endpoint should be peered. Private services access must already be configured for the network. If left unspecified, the Endpoint is not peered with any network. + Only one of the fields, + [network][google.cloud.aiplatform.v1beta1.Endpoint.network] + or + [enable_private_service_connect][google.cloud.aiplatform.v1beta1.Endpoint.enable_private_service_connect], + can be set. + `Format `__: - projects/{project}/global/networks/{network}. Where - {project} is a project number, as in '12345', and {network} - is network name. + ``projects/{project}/global/networks/{network}``. Where + ``{project}`` is a project number, as in ``12345``, and + ``{network}`` is network name. + enable_private_service_connect (bool): + If true, expose the Endpoint via private service connect. + + Only one of the fields, + [network][google.cloud.aiplatform.v1beta1.Endpoint.network] + or + [enable_private_service_connect][google.cloud.aiplatform.v1beta1.Endpoint.enable_private_service_connect], + can be set. model_deployment_monitoring_job (str): Output only. Resource name of the Model Monitoring job associated with this Endpoint if monitoring is enabled by @@ -118,6 +132,7 @@ class Endpoint(proto.Message): proto.MESSAGE, number=10, message=gca_encryption_spec.EncryptionSpec, ) network = proto.Field(proto.STRING, number=13,) + enable_private_service_connect = proto.Field(proto.BOOL, number=17,) model_deployment_monitoring_job = proto.Field(proto.STRING, number=14,) @@ -137,14 +152,20 @@ class DeployedModel(proto.Message): A description of resources that are dedicated to the DeployedModel, and that need a higher degree of manual configuration. + This field is a member of `oneof`_ ``prediction_resources``. automatic_resources (google.cloud.aiplatform_v1beta1.types.AutomaticResources): A description of resources that to large degree are decided by Vertex AI, and require only a modest additional configuration. + This field is a member of `oneof`_ ``prediction_resources``. id (str): - Output only. The ID of the DeployedModel. + Immutable. The ID of the DeployedModel. If not provided upon + deployment, Vertex AI will generate a value for this ID. + + This value should be 1-10 characters, and valid characters + are /[0-9]/. model (str): Required. The name of the Model that this is the deployment of. Note that the Model may be in @@ -237,8 +258,10 @@ class DeployedModel(proto.Message): class PrivateEndpoints(proto.Message): - r"""PrivateEndpoints is used to provide paths for users to send - requests via private services access. + r"""PrivateEndpoints proto is used to provide paths for users to send + requests privately. To send request via private service access, use + predict_http_uri, explain_http_uri or health_http_uri. To send + request via private service connect, use service_attachment. Attributes: predict_http_uri (str): @@ -250,11 +273,16 @@ class PrivateEndpoints(proto.Message): health_http_uri (str): Output only. Http(s) path to send health check requests. + service_attachment (str): + Output only. The name of the service + attachment resource. Populated if private + service connect is enabled. """ predict_http_uri = proto.Field(proto.STRING, number=1,) explain_http_uri = proto.Field(proto.STRING, number=2,) health_http_uri = proto.Field(proto.STRING, number=3,) + service_attachment = proto.Field(proto.STRING, number=4,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1beta1/types/endpoint_service.py b/google/cloud/aiplatform_v1beta1/types/endpoint_service.py index 94b28acec2..a21d1ca933 100644 --- a/google/cloud/aiplatform_v1beta1/types/endpoint_service.py +++ b/google/cloud/aiplatform_v1beta1/types/endpoint_service.py @@ -51,10 +51,21 @@ class CreateEndpointRequest(proto.Message): ``projects/{project}/locations/{location}`` endpoint (google.cloud.aiplatform_v1beta1.types.Endpoint): Required. The Endpoint to create. + endpoint_id (str): + Immutable. The ID to use for endpoint, which will become the + final component of the endpoint resource name. If not + provided, Vertex AI will generate a value for this ID. + + This value should be 1-10 characters, and valid characters + are /[0-9]/. When using HTTP/JSON, this field is populated + based on a query string argument, such as + ``?endpoint_id=12345``. This is the fallback for fields that + are not included in either the URI or the body. """ parent = proto.Field(proto.STRING, number=1,) endpoint = proto.Field(proto.MESSAGE, number=2, message=gca_endpoint.Endpoint,) + endpoint_id = proto.Field(proto.STRING, number=4,) class CreateEndpointOperationMetadata(proto.Message): diff --git a/google/cloud/aiplatform_v1beta1/types/execution.py b/google/cloud/aiplatform_v1beta1/types/execution.py index 3dd91ffa6b..85b824ac50 100644 --- a/google/cloud/aiplatform_v1beta1/types/execution.py +++ b/google/cloud/aiplatform_v1beta1/types/execution.py @@ -38,7 +38,7 @@ class Execution(proto.Message): The state of this Execution. This is a property of the Execution, and does not imply or capture any ongoing process. This property is - managed by clients (such as Vertex Pipelines) + managed by clients (such as Vertex AI Pipelines) and the system does not prescribe or check the validity of state transitions. etag (str): diff --git a/google/cloud/aiplatform_v1beta1/types/explanation.py b/google/cloud/aiplatform_v1beta1/types/explanation.py index 95ce01508e..2972aa2183 100644 --- a/google/cloud/aiplatform_v1beta1/types/explanation.py +++ b/google/cloud/aiplatform_v1beta1/types/explanation.py @@ -33,6 +33,7 @@ "XraiAttribution", "SmoothGradConfig", "FeatureNoiseSigma", + "BlurBaselineConfig", "Similarity", "ExplanationSpecOverride", "ExplanationMetadataOverride", @@ -278,6 +279,7 @@ class ExplanationParameters(proto.Message): considering all subsets of features. Refer to this paper for model details: https://arxiv.org/abs/1306.4265. + This field is a member of `oneof`_ ``method``. integrated_gradients_attribution (google.cloud.aiplatform_v1beta1.types.IntegratedGradientsAttribution): An attribution method that computes Aumann- @@ -285,6 +287,7 @@ class ExplanationParameters(proto.Message): fully differentiable structure. Refer to this paper for more details: https://arxiv.org/abs/1703.01365 + This field is a member of `oneof`_ ``method``. xrai_attribution (google.cloud.aiplatform_v1beta1.types.XraiAttribution): An attribution method that redistributes @@ -300,10 +303,12 @@ class ExplanationParameters(proto.Message): or from diagnostic equipment, like x-rays or quality-control cameras, use Integrated Gradients instead. + This field is a member of `oneof`_ ``method``. similarity (google.cloud.aiplatform_v1beta1.types.Similarity): Similarity explainability that returns the nearest neighbors from the provided dataset. + This field is a member of `oneof`_ ``method``. top_k (int): If populated, returns attributions for top K @@ -385,12 +390,22 @@ class IntegratedGradientsAttribution(proto.Message): help improve the computed gradients. Refer to this paper for more details: https://arxiv.org/pdf/1706.03825.pdf + blur_baseline_config (google.cloud.aiplatform_v1beta1.types.BlurBaselineConfig): + Config for IG with blur baseline. + When enabled, a linear path from the maximally + blurred image to the input image is created. + Using a blurred baseline instead of zero (black + image) is motivated by the BlurIG approach + explained here: https://arxiv.org/abs/2004.03383 """ step_count = proto.Field(proto.INT32, number=1,) smooth_grad_config = proto.Field( proto.MESSAGE, number=2, message="SmoothGradConfig", ) + blur_baseline_config = proto.Field( + proto.MESSAGE, number=3, message="BlurBaselineConfig", + ) class XraiAttribution(proto.Message): @@ -418,12 +433,22 @@ class XraiAttribution(proto.Message): help improve the computed gradients. Refer to this paper for more details: https://arxiv.org/pdf/1706.03825.pdf + blur_baseline_config (google.cloud.aiplatform_v1beta1.types.BlurBaselineConfig): + Config for XRAI with blur baseline. + When enabled, a linear path from the maximally + blurred image to the input image is created. + Using a blurred baseline instead of zero (black + image) is motivated by the BlurIG approach + explained here: https://arxiv.org/abs/2004.03383 """ step_count = proto.Field(proto.INT32, number=1,) smooth_grad_config = proto.Field( proto.MESSAGE, number=2, message="SmoothGradConfig", ) + blur_baseline_config = proto.Field( + proto.MESSAGE, number=3, message="BlurBaselineConfig", + ) class SmoothGradConfig(proto.Message): @@ -458,6 +483,7 @@ class SmoothGradConfig(proto.Message): If the distribution is different per feature, set [feature_noise_sigma][google.cloud.aiplatform.v1beta1.SmoothGradConfig.feature_noise_sigma] instead for each feature. + This field is a member of `oneof`_ ``GradientNoiseSigma``. feature_noise_sigma (google.cloud.aiplatform_v1beta1.types.FeatureNoiseSigma): This is similar to @@ -468,6 +494,7 @@ class SmoothGradConfig(proto.Message): that are not set. If this field is unset, [noise_sigma][google.cloud.aiplatform.v1beta1.SmoothGradConfig.noise_sigma] will be used for all features. + This field is a member of `oneof`_ ``GradientNoiseSigma``. noisy_sample_count (int): The number of gradient samples to use for approximation. The @@ -522,6 +549,26 @@ class NoiseSigmaForFeature(proto.Message): ) +class BlurBaselineConfig(proto.Message): + r"""Config for blur baseline. + When enabled, a linear path from the maximally blurred image to + the input image is created. Using a blurred baseline instead of + zero (black image) is motivated by the BlurIG approach explained + here: + https://arxiv.org/abs/2004.03383 + + Attributes: + max_blur_sigma (float): + The standard deviation of the blur kernel for + the blurred baseline. The same blurring + parameter is used for both the height and the + width dimension. If not set, the method defaults + to the zero (i.e. black for images) baseline. + """ + + max_blur_sigma = proto.Field(proto.FLOAT, number=1,) + + class Similarity(proto.Message): r"""Similarity explainability that returns the nearest neighbors from the provided dataset. diff --git a/google/cloud/aiplatform_v1beta1/types/explanation_metadata.py b/google/cloud/aiplatform_v1beta1/types/explanation_metadata.py index 78acb0029e..a17467a920 100644 --- a/google/cloud/aiplatform_v1beta1/types/explanation_metadata.py +++ b/google/cloud/aiplatform_v1beta1/types/explanation_metadata.py @@ -356,6 +356,7 @@ class OutputMetadata(proto.Message): [Attribution.output_display_name][google.cloud.aiplatform.v1beta1.Attribution.output_display_name] is populated by locating in the mapping with [Attribution.output_index][google.cloud.aiplatform.v1beta1.Attribution.output_index]. + This field is a member of `oneof`_ ``display_name_mapping``. display_name_mapping_key (str): Specify a field name in the prediction to look for the @@ -368,6 +369,7 @@ class OutputMetadata(proto.Message): of the outputs, so that it can be located by [Attribution.output_index][google.cloud.aiplatform.v1beta1.Attribution.output_index] for a specific output. + This field is a member of `oneof`_ ``display_name_mapping``. output_tensor_name (str): Name of the output tensor. Required and is diff --git a/google/cloud/aiplatform_v1beta1/types/feature.py b/google/cloud/aiplatform_v1beta1/types/feature.py index 1d8ec6500f..7e056694fe 100644 --- a/google/cloud/aiplatform_v1beta1/types/feature.py +++ b/google/cloud/aiplatform_v1beta1/types/feature.py @@ -85,7 +85,7 @@ class Feature(proto.Message): the EntityType's this Feature belongs to. monitoring_stats (Sequence[google.cloud.aiplatform_v1beta1.types.FeatureStatsAnomaly]): Output only. A list of historical [Snapshot - Analysis][google.cloud.aiplatform.master.FeaturestoreMonitoringConfig.SnapshotAnalysis] + Analysis][FeaturestoreMonitoringConfig.SnapshotAnalysis] stats requested by user, sorted by [FeatureStatsAnomaly.start_time][google.cloud.aiplatform.v1beta1.FeatureStatsAnomaly.start_time] descending. diff --git a/google/cloud/aiplatform_v1beta1/types/featurestore.py b/google/cloud/aiplatform_v1beta1/types/featurestore.py index a15904b9af..203dfc4a68 100644 --- a/google/cloud/aiplatform_v1beta1/types/featurestore.py +++ b/google/cloud/aiplatform_v1beta1/types/featurestore.py @@ -25,8 +25,9 @@ class Featurestore(proto.Message): - r"""Featurestore configuration information on how the - Featurestore is configured. + r"""Vertex AI Feature Store provides a centralized repository for + organizing, storing, and serving ML features. The Featurestore + is a top-level container for your features and their values. Attributes: name (str): diff --git a/google/cloud/aiplatform_v1beta1/types/featurestore_online_service.py b/google/cloud/aiplatform_v1beta1/types/featurestore_online_service.py index 3e4ed77015..25a42f0bff 100644 --- a/google/cloud/aiplatform_v1beta1/types/featurestore_online_service.py +++ b/google/cloud/aiplatform_v1beta1/types/featurestore_online_service.py @@ -138,6 +138,7 @@ class Data(proto.Message): Attributes: value (google.cloud.aiplatform_v1beta1.types.FeatureValue): Feature value if a single value is requested. + This field is a member of `oneof`_ ``data``. values (google.cloud.aiplatform_v1beta1.types.FeatureValueList): Feature values list if values, successive in @@ -145,6 +146,7 @@ class Data(proto.Message): values is greater than the number of existing Feature values, nonexistent values are omitted instead of being returned as empty. + This field is a member of `oneof`_ ``data``. """ @@ -209,30 +211,39 @@ class FeatureValue(proto.Message): Attributes: bool_value (bool): Bool type feature value. + This field is a member of `oneof`_ ``value``. double_value (float): Double type feature value. + This field is a member of `oneof`_ ``value``. int64_value (int): Int64 feature value. + This field is a member of `oneof`_ ``value``. string_value (str): String feature value. + This field is a member of `oneof`_ ``value``. bool_array_value (google.cloud.aiplatform_v1beta1.types.BoolArray): A list of bool type feature value. + This field is a member of `oneof`_ ``value``. double_array_value (google.cloud.aiplatform_v1beta1.types.DoubleArray): A list of double type feature value. + This field is a member of `oneof`_ ``value``. int64_array_value (google.cloud.aiplatform_v1beta1.types.Int64Array): A list of int64 type feature value. + This field is a member of `oneof`_ ``value``. string_array_value (google.cloud.aiplatform_v1beta1.types.StringArray): A list of string type feature value. + This field is a member of `oneof`_ ``value``. bytes_value (bytes): Bytes feature value. + This field is a member of `oneof`_ ``value``. metadata (google.cloud.aiplatform_v1beta1.types.FeatureValue.Metadata): Metadata of feature value. @@ -247,7 +258,10 @@ class Metadata(proto.Message): is provided by user at feature ingestion time. If not, feature store will use the system timestamp when the data is ingested into feature - store. + store. For streaming ingestion, the time, + aligned by days, must be no older than five + years (1825 days) and no later than one year + (366 days) in the future. """ generate_time = proto.Field( diff --git a/google/cloud/aiplatform_v1beta1/types/featurestore_service.py b/google/cloud/aiplatform_v1beta1/types/featurestore_service.py index 43a6a4df44..f5c20abdd4 100644 --- a/google/cloud/aiplatform_v1beta1/types/featurestore_service.py +++ b/google/cloud/aiplatform_v1beta1/types/featurestore_service.py @@ -279,11 +279,13 @@ class ImportFeatureValuesRequest(proto.Message): feature_time_field (str): Source column that holds the Feature timestamp for all Feature values in each entity. + This field is a member of `oneof`_ ``feature_time_source``. feature_time (google.protobuf.timestamp_pb2.Timestamp): Single Feature timestamp for all entities being imported. The timestamp must not have higher than millisecond precision. + This field is a member of `oneof`_ ``feature_time_source``. entity_type (str): Required. The resource name of the EntityType grouping the @@ -418,9 +420,11 @@ class BatchReadFeatureValuesRequest(proto.Message): Values in the timestamp column must use the RFC 3339 format, e.g. ``2012-07-30T10:43:17.123Z``. + This field is a member of `oneof`_ ``read_option``. bigquery_read_instances (google.cloud.aiplatform_v1beta1.types.BigQuerySource): Similar to csv_read_instances, but from BigQuery source. + This field is a member of `oneof`_ ``read_option``. featurestore (str): Required. The resource name of the Featurestore from which @@ -505,13 +509,23 @@ class ExportFeatureValuesRequest(proto.Message): r"""Request message for [FeaturestoreService.ExportFeatureValues][google.cloud.aiplatform.v1beta1.FeaturestoreService.ExportFeatureValues]. + 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: snapshot_export (google.cloud.aiplatform_v1beta1.types.ExportFeatureValuesRequest.SnapshotExport): - Exports Feature values of all entities of the - EntityType as of a snapshot time. + Exports the latest Feature values of all + entities of the EntityType within a time range. + + This field is a member of `oneof`_ ``mode``. + full_export (google.cloud.aiplatform_v1beta1.types.ExportFeatureValuesRequest.FullExport): + Exports all historical values of all entities + of the EntityType within a time range + This field is a member of `oneof`_ ``mode``. entity_type (str): Required. The resource name of the EntityType from which to @@ -528,8 +542,8 @@ class ExportFeatureValuesRequest(proto.Message): """ class SnapshotExport(proto.Message): - r"""Describes exporting Feature values as of the snapshot - timestamp. + r"""Describes exporting the latest Feature values of all entities of the + EntityType between [start_time, snapshot_time]. Attributes: snapshot_time (google.protobuf.timestamp_pb2.Timestamp): @@ -537,15 +551,52 @@ class SnapshotExport(proto.Message): If not set, retrieve values as of now. Timestamp, if present, must not have higher than millisecond precision. + start_time (google.protobuf.timestamp_pb2.Timestamp): + Excludes Feature values with feature + generation timestamp before this timestamp. If + not set, retrieve oldest values kept in Feature + Store. Timestamp, if present, must not have + higher than millisecond precision. """ snapshot_time = proto.Field( proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp, ) + start_time = proto.Field( + proto.MESSAGE, number=2, message=timestamp_pb2.Timestamp, + ) + + class FullExport(proto.Message): + r"""Describes exporting all historical Feature values of all entities of + the EntityType between [start_time, end_time]. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Excludes Feature values with feature + generation timestamp before this timestamp. If + not set, retrieve oldest values kept in Feature + Store. Timestamp, if present, must not have + higher than millisecond precision. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Exports Feature values as of this timestamp. + If not set, retrieve values as of now. + Timestamp, if present, must not have higher than + millisecond precision. + """ + + start_time = proto.Field( + proto.MESSAGE, number=2, message=timestamp_pb2.Timestamp, + ) + end_time = proto.Field( + proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp, + ) snapshot_export = proto.Field( proto.MESSAGE, number=3, oneof="mode", message=SnapshotExport, ) + full_export = proto.Field( + proto.MESSAGE, number=7, oneof="mode", message=FullExport, + ) entity_type = proto.Field(proto.STRING, number=1,) destination = proto.Field( proto.MESSAGE, number=4, message="FeatureValueDestination", @@ -592,6 +643,7 @@ class FeatureValueDestination(proto.Message): in [FeatureValueDestination.bigquery_destination][google.cloud.aiplatform.v1beta1.FeatureValueDestination.bigquery_destination] must refer to a table. + This field is a member of `oneof`_ ``destination``. tfrecord_destination (google.cloud.aiplatform_v1beta1.types.TFRecordDestination): Output in TFRecord format. @@ -607,10 +659,12 @@ class FeatureValueDestination(proto.Message): STRING, STRING_ARRAY, BYTES | BYTES_LIST true -> byte_string("true"), false -> byte_string("false") BOOL, BOOL_ARRAY (true, false) | BYTES_LIST + This field is a member of `oneof`_ ``destination``. csv_destination (google.cloud.aiplatform_v1beta1.types.CsvDestination): Output in CSV format. Array Feature value types are not allowed in CSV format. + This field is a member of `oneof`_ ``destination``. """ @@ -1208,17 +1262,17 @@ class UpdateFeaturestoreOperationMetadata(proto.Message): class ImportFeatureValuesOperationMetadata(proto.Message): - r"""Details of operations that perform import feature values. + r"""Details of operations that perform import Feature values. Attributes: generic_metadata (google.cloud.aiplatform_v1beta1.types.GenericOperationMetadata): Operation metadata for Featurestore import - feature values. + Feature values. imported_entity_count (int): Number of entities that have been imported by the operation. imported_feature_value_count (int): - Number of feature values that have been + Number of Feature values that have been imported by the operation. invalid_row_count (int): The number of rows in input source that weren't imported due diff --git a/google/cloud/aiplatform_v1beta1/types/index_endpoint.py b/google/cloud/aiplatform_v1beta1/types/index_endpoint.py index 0739c547c8..c423957375 100644 --- a/google/cloud/aiplatform_v1beta1/types/index_endpoint.py +++ b/google/cloud/aiplatform_v1beta1/types/index_endpoint.py @@ -73,8 +73,7 @@ class IndexEndpoint(proto.Message): of the original Indexes they are the deployments of. network (str): - Required. Immutable. The full name of the Google Compute - Engine + Optional. The full name of the Google Compute Engine `network `__ to which the IndexEndpoint should be peered. @@ -82,10 +81,25 @@ class IndexEndpoint(proto.Message): network. If left unspecified, the Endpoint is not peered with any network. + Only one of the fields, + [network][google.cloud.aiplatform.v1beta1.IndexEndpoint.network] + or + [enable_private_service_connect][google.cloud.aiplatform.v1beta1.IndexEndpoint.enable_private_service_connect], + can be set. + `Format `__: projects/{project}/global/networks/{network}. Where {project} is a project number, as in '12345', and {network} is network name. + enable_private_service_connect (bool): + Optional. If true, expose the IndexEndpoint via private + service connect. + + Only one of the fields, + [network][google.cloud.aiplatform.v1beta1.IndexEndpoint.network] + or + [enable_private_service_connect][google.cloud.aiplatform.v1beta1.IndexEndpoint.enable_private_service_connect], + can be set. """ name = proto.Field(proto.STRING, number=1,) @@ -99,6 +113,7 @@ class IndexEndpoint(proto.Message): create_time = proto.Field(proto.MESSAGE, number=7, message=timestamp_pb2.Timestamp,) update_time = proto.Field(proto.MESSAGE, number=8, message=timestamp_pb2.Timestamp,) network = proto.Field(proto.STRING, number=9,) + enable_private_service_connect = proto.Field(proto.BOOL, number=10,) class DeployedIndex(proto.Message): @@ -152,11 +167,10 @@ class DeployedIndex(proto.Message): Optional. A description of resources that the DeployedIndex uses, which to large degree are decided by Vertex AI, and optionally allows only a modest additional configuration. If - min_replica_count is not set, the default value is 1. If + min_replica_count is not set, the default value is 2 (we + don't provide SLA when min_replica_count=1). If max_replica_count is not set, the default value is min_replica_count. The max allowed replica count is 1000. - The user is billed for the resources (at least their minimal - amount) even if the DeployedIndex receives no traffic. enable_access_logging (bool): Optional. If true, private endpoint's access logs are sent to StackDriver Logging. @@ -256,16 +270,24 @@ class AuthProvider(proto.Message): class IndexPrivateEndpoints(proto.Message): - r"""IndexPrivateEndpoints proto is used to provide paths for - users to send requests via private services access. + r"""IndexPrivateEndpoints proto is used to provide paths for users to + send requests via private endpoints (e.g. private service access, + private service connect). To send request via private service + access, use match_grpc_address. To send request via private service + connect, use service_attachment. Attributes: match_grpc_address (str): Output only. The ip address used to send match gRPC requests. + service_attachment (str): + Output only. The name of the service + attachment resource. Populated if private + service connect is enabled. """ match_grpc_address = proto.Field(proto.STRING, number=1,) + service_attachment = proto.Field(proto.STRING, number=2,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1beta1/types/index_endpoint_service.py b/google/cloud/aiplatform_v1beta1/types/index_endpoint_service.py index 69840b8899..fa8928ca4f 100644 --- a/google/cloud/aiplatform_v1beta1/types/index_endpoint_service.py +++ b/google/cloud/aiplatform_v1beta1/types/index_endpoint_service.py @@ -36,6 +36,9 @@ "UndeployIndexRequest", "UndeployIndexResponse", "UndeployIndexOperationMetadata", + "MutateDeployedIndexRequest", + "MutateDeployedIndexResponse", + "MutateDeployedIndexOperationMetadata", }, ) @@ -289,4 +292,58 @@ class UndeployIndexOperationMetadata(proto.Message): ) +class MutateDeployedIndexRequest(proto.Message): + r"""Request message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1beta1.IndexEndpointService.MutateDeployedIndex]. + + Attributes: + index_endpoint (str): + Required. The name of the IndexEndpoint resource into which + to deploy an Index. Format: + ``projects/{project}/locations/{location}/indexEndpoints/{index_endpoint}`` + deployed_index (google.cloud.aiplatform_v1beta1.types.DeployedIndex): + Required. The DeployedIndex to be updated within the + IndexEndpoint. Currently, the updatable fields are + [DeployedIndex][automatic_resources] and + [DeployedIndex][dedicated_resources] + """ + + index_endpoint = proto.Field(proto.STRING, number=1,) + deployed_index = proto.Field( + proto.MESSAGE, number=2, message=gca_index_endpoint.DeployedIndex, + ) + + +class MutateDeployedIndexResponse(proto.Message): + r"""Response message for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1beta1.IndexEndpointService.MutateDeployedIndex]. + + Attributes: + deployed_index (google.cloud.aiplatform_v1beta1.types.DeployedIndex): + The DeployedIndex that had been updated in + the IndexEndpoint. + """ + + deployed_index = proto.Field( + proto.MESSAGE, number=1, message=gca_index_endpoint.DeployedIndex, + ) + + +class MutateDeployedIndexOperationMetadata(proto.Message): + r"""Runtime operation information for + [IndexEndpointService.MutateDeployedIndex][google.cloud.aiplatform.v1beta1.IndexEndpointService.MutateDeployedIndex]. + + Attributes: + generic_metadata (google.cloud.aiplatform_v1beta1.types.GenericOperationMetadata): + The operation generic information. + deployed_index_id (str): + The unique index id specified by user + """ + + generic_metadata = proto.Field( + proto.MESSAGE, number=1, message=operation.GenericOperationMetadata, + ) + deployed_index_id = proto.Field(proto.STRING, number=2,) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1beta1/types/job_service.py b/google/cloud/aiplatform_v1beta1/types/job_service.py index 4d34ca0100..0988a81f3c 100644 --- a/google/cloud/aiplatform_v1beta1/types/job_service.py +++ b/google/cloud/aiplatform_v1beta1/types/job_service.py @@ -633,7 +633,7 @@ class SearchModelDeploymentMonitoringStatsAnomaliesRequest(proto.Message): \`projects/{project}/locations/{location}/modelDeploymentMonitoringJobs/{model_deployment_monitoring_job} deployed_model_id (str): Required. The DeployedModel ID of the - [google.cloud.aiplatform.master.ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. + [ModelDeploymentMonitoringObjectiveConfig.deployed_model_id]. feature_display_name (str): The feature display name. If specified, only return the stats belonging to this feature. Format: diff --git a/google/cloud/aiplatform_v1beta1/types/metadata_schema.py b/google/cloud/aiplatform_v1beta1/types/metadata_schema.py index 34cca83420..69642111fb 100644 --- a/google/cloud/aiplatform_v1beta1/types/metadata_schema.py +++ b/google/cloud/aiplatform_v1beta1/types/metadata_schema.py @@ -34,7 +34,8 @@ class MetadataSchema(proto.Message): The version of the MetadataSchema. The version's format must match the following regular expression: ``^[0-9]+[.][0-9]+[.][0-9]+$``, which would allow to - order/compare different versions.Example: 1.0.0, 1.0.1, etc. + order/compare different versions. Example: 1.0.0, 1.0.1, + etc. schema (str): Required. The raw YAML string representation of the MetadataSchema. The combination of [MetadataSchema.version] diff --git a/google/cloud/aiplatform_v1beta1/types/migratable_resource.py b/google/cloud/aiplatform_v1beta1/types/migratable_resource.py index df9b7fb826..2a95818685 100644 --- a/google/cloud/aiplatform_v1beta1/types/migratable_resource.py +++ b/google/cloud/aiplatform_v1beta1/types/migratable_resource.py @@ -38,18 +38,22 @@ class MigratableResource(proto.Message): ml_engine_model_version (google.cloud.aiplatform_v1beta1.types.MigratableResource.MlEngineModelVersion): Output only. Represents one Version in ml.googleapis.com. + This field is a member of `oneof`_ ``resource``. automl_model (google.cloud.aiplatform_v1beta1.types.MigratableResource.AutomlModel): Output only. Represents one Model in automl.googleapis.com. + This field is a member of `oneof`_ ``resource``. automl_dataset (google.cloud.aiplatform_v1beta1.types.MigratableResource.AutomlDataset): Output only. Represents one Dataset in automl.googleapis.com. + This field is a member of `oneof`_ ``resource``. data_labeling_dataset (google.cloud.aiplatform_v1beta1.types.MigratableResource.DataLabelingDataset): Output only. Represents one Dataset in datalabeling.googleapis.com. + This field is a member of `oneof`_ ``resource``. last_migrate_time (google.protobuf.timestamp_pb2.Timestamp): Output only. Timestamp when the last diff --git a/google/cloud/aiplatform_v1beta1/types/migration_service.py b/google/cloud/aiplatform_v1beta1/types/migration_service.py index 2a9bedc759..71c0ac809c 100644 --- a/google/cloud/aiplatform_v1beta1/types/migration_service.py +++ b/google/cloud/aiplatform_v1beta1/types/migration_service.py @@ -141,19 +141,23 @@ class MigrateResourceRequest(proto.Message): migrate_ml_engine_model_version_config (google.cloud.aiplatform_v1beta1.types.MigrateResourceRequest.MigrateMlEngineModelVersionConfig): Config for migrating Version in ml.googleapis.com to Vertex AI's Model. + This field is a member of `oneof`_ ``request``. migrate_automl_model_config (google.cloud.aiplatform_v1beta1.types.MigrateResourceRequest.MigrateAutomlModelConfig): Config for migrating Model in automl.googleapis.com to Vertex AI's Model. + This field is a member of `oneof`_ ``request``. migrate_automl_dataset_config (google.cloud.aiplatform_v1beta1.types.MigrateResourceRequest.MigrateAutomlDatasetConfig): Config for migrating Dataset in automl.googleapis.com to Vertex AI's Dataset. + This field is a member of `oneof`_ ``request``. migrate_data_labeling_dataset_config (google.cloud.aiplatform_v1beta1.types.MigrateResourceRequest.MigrateDataLabelingDatasetConfig): Config for migrating Dataset in datalabeling.googleapis.com to Vertex AI's Dataset. + This field is a member of `oneof`_ ``request``. """ @@ -309,9 +313,11 @@ class MigrateResourceResponse(proto.Message): Attributes: dataset (str): Migrated Dataset's resource name. + This field is a member of `oneof`_ ``migrated_resource``. model (str): Migrated Model's resource name. + This field is a member of `oneof`_ ``migrated_resource``. migratable_resource (google.cloud.aiplatform_v1beta1.types.MigratableResource): Before migration, the identifier in @@ -353,12 +359,15 @@ class PartialResult(proto.Message): error (google.rpc.status_pb2.Status): The error result of the migration request in case of failure. + This field is a member of `oneof`_ ``result``. model (str): Migrated model resource name. + This field is a member of `oneof`_ ``result``. dataset (str): Migrated dataset resource name. + This field is a member of `oneof`_ ``result``. request (google.cloud.aiplatform_v1beta1.types.MigrateResourceRequest): It's the same as the value in diff --git a/google/cloud/aiplatform_v1beta1/types/model_deployment_monitoring_job.py b/google/cloud/aiplatform_v1beta1/types/model_deployment_monitoring_job.py index 5bf590b7c1..b9a106c639 100644 --- a/google/cloud/aiplatform_v1beta1/types/model_deployment_monitoring_job.py +++ b/google/cloud/aiplatform_v1beta1/types/model_deployment_monitoring_job.py @@ -162,9 +162,10 @@ class ModelDeploymentMonitoringJob(proto.Message): resources of this ModelDeploymentMonitoringJob will be secured by this key. enable_monitoring_pipeline_logs (bool): - If true, the scheduled monitoring pipeline status logs are - sent to Google Cloud Logging. Please note the logs incur - cost, which are subject to `Cloud Logging + If true, the scheduled monitoring pipeline logs are sent to + Google Cloud Logging, including pipeline status and + anomalies detected. Please note the logs incur cost, which + are subject to `Cloud Logging pricing `__. error (google.rpc.status_pb2.Status): Output only. Only populated when the job's state is diff --git a/google/cloud/aiplatform_v1beta1/types/model_monitoring.py b/google/cloud/aiplatform_v1beta1/types/model_monitoring.py index ccf00adf01..760ac63c2f 100644 --- a/google/cloud/aiplatform_v1beta1/types/model_monitoring.py +++ b/google/cloud/aiplatform_v1beta1/types/model_monitoring.py @@ -44,8 +44,8 @@ class ModelMonitoringObjectiveConfig(proto.Message): prediction_drift_detection_config (google.cloud.aiplatform_v1beta1.types.ModelMonitoringObjectiveConfig.PredictionDriftDetectionConfig): The config for drift of prediction data. explanation_config (google.cloud.aiplatform_v1beta1.types.ModelMonitoringObjectiveConfig.ExplanationConfig): - The config for integrated with Explainable - AI. + The config for integrating with Vertex + Explainable AI. """ class TrainingDataset(proto.Message): @@ -62,14 +62,17 @@ class TrainingDataset(proto.Message): dataset (str): The resource name of the Dataset used to train this Model. + This field is a member of `oneof`_ ``data_source``. gcs_source (google.cloud.aiplatform_v1beta1.types.GcsSource): The Google Cloud Storage uri of the unmanaged Dataset used to train this Model. + This field is a member of `oneof`_ ``data_source``. bigquery_source (google.cloud.aiplatform_v1beta1.types.BigQuerySource): The BigQuery table of the unmanaged Dataset used to train this Model. + This field is a member of `oneof`_ ``data_source``. data_format (str): Data format of the dataset, only applicable @@ -157,14 +160,14 @@ class PredictionDriftDetectionConfig(proto.Message): ) class ExplanationConfig(proto.Message): - r"""The config for integrated with Explainable AI. Only applicable if - the Model has explanation_spec populated. + r"""The config for integrating with Vertex Explainable AI. Only + applicable if the Model has explanation_spec populated. Attributes: enable_feature_attributes (bool): - If want to analyze the Explainable AI feature - attribute scores or not. If set to true, Vertex - AI will log the feature attributions from + If want to analyze the Vertex Explainable AI + feature attribute scores or not. If set to true, + Vertex AI will log the feature attributions from explain response and do the skew/drift detection for them. explanation_baseline (google.cloud.aiplatform_v1beta1.types.ModelMonitoringObjectiveConfig.ExplanationConfig.ExplanationBaseline): @@ -189,9 +192,11 @@ class ExplanationBaseline(proto.Message): gcs (google.cloud.aiplatform_v1beta1.types.GcsDestination): Cloud Storage location for BatchExplain output. + This field is a member of `oneof`_ ``destination``. bigquery (google.cloud.aiplatform_v1beta1.types.BigQueryDestination): BigQuery location for BatchExplain output. + This field is a member of `oneof`_ ``destination``. prediction_format (google.cloud.aiplatform_v1beta1.types.ModelMonitoringObjectiveConfig.ExplanationConfig.ExplanationBaseline.PredictionFormat): The storage format of the predictions @@ -241,14 +246,21 @@ class PredictionFormat(proto.Enum): class ModelMonitoringAlertConfig(proto.Message): - r"""Next ID: 2 + r"""Next ID: 3 .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: email_alert_config (google.cloud.aiplatform_v1beta1.types.ModelMonitoringAlertConfig.EmailAlertConfig): Email alert config. + This field is a member of `oneof`_ ``alert``. + enable_logging (bool): + Dump the anomalies to Cloud Logging. The anomalies will be + put to json payload encoded from proto + [google.cloud.aiplatform.logging.ModelMonitoringAnomaliesLogEntry][]. + This can be further sinked to Pub/Sub or any other services + supported by Cloud Logging. """ class EmailAlertConfig(proto.Message): @@ -264,6 +276,7 @@ class EmailAlertConfig(proto.Message): email_alert_config = proto.Field( proto.MESSAGE, number=1, oneof="alert", message=EmailAlertConfig, ) + enable_logging = proto.Field(proto.BOOL, number=2,) class ThresholdConfig(proto.Message): @@ -286,6 +299,7 @@ class ThresholdConfig(proto.Message): Each feature must have a non-zero threshold if they need to be monitored. Otherwise no alert will be triggered for that feature. + This field is a member of `oneof`_ ``threshold``. """ diff --git a/google/cloud/aiplatform_v1beta1/types/pipeline_job.py b/google/cloud/aiplatform_v1beta1/types/pipeline_job.py index 13388ef271..c9c7d6d861 100644 --- a/google/cloud/aiplatform_v1beta1/types/pipeline_job.py +++ b/google/cloud/aiplatform_v1beta1/types/pipeline_job.py @@ -116,11 +116,16 @@ class RuntimeConfig(proto.Message): Attributes: parameters (Sequence[google.cloud.aiplatform_v1beta1.types.PipelineJob.RuntimeConfig.ParametersEntry]): - Deprecated. Use [RuntimeConfig.parameter_values] instead. - The runtime parameters of the PipelineJob. The parameters - will be passed into + Deprecated. Use + [RuntimeConfig.parameter_values][google.cloud.aiplatform.v1beta1.PipelineJob.RuntimeConfig.parameter_values] + instead. The runtime parameters of the PipelineJob. The + parameters will be passed into [PipelineJob.pipeline_spec][google.cloud.aiplatform.v1beta1.PipelineJob.pipeline_spec] - to replace the placeholders at runtime. + to replace the placeholders at runtime. This field is used + by pipelines built using + ``PipelineJob.pipeline_spec.schema_version`` 2.0.0 or lower, + such as pipelines built using Kubeflow Pipelines SDK 1.8 or + lower. gcs_output_directory (str): Required. A path in a Cloud Storage bucket, which will be treated as the root output directory of the pipeline. It is @@ -134,7 +139,11 @@ class RuntimeConfig(proto.Message): The runtime parameters of the PipelineJob. The parameters will be passed into [PipelineJob.pipeline_spec][google.cloud.aiplatform.v1beta1.PipelineJob.pipeline_spec] - to replace the placeholders at runtime. + to replace the placeholders at runtime. This field is used + by pipelines built using + ``PipelineJob.pipeline_spec.schema_version`` 2.1.0, such as + pipelines built using Kubeflow Pipelines SDK 1.9 or higher + and the v2 DSL. """ parameters = proto.MapField( @@ -316,10 +325,12 @@ class PipelineTaskExecutorDetail(proto.Message): container_detail (google.cloud.aiplatform_v1beta1.types.PipelineTaskExecutorDetail.ContainerDetail): Output only. The detailed info for a container executor. + This field is a member of `oneof`_ ``details``. custom_job_detail (google.cloud.aiplatform_v1beta1.types.PipelineTaskExecutorDetail.CustomJobDetail): Output only. The detailed info for a custom job executor. + This field is a member of `oneof`_ ``details``. """ diff --git a/google/cloud/aiplatform_v1beta1/types/pipeline_service.py b/google/cloud/aiplatform_v1beta1/types/pipeline_service.py index e2dc3139b6..902bee0ba8 100644 --- a/google/cloud/aiplatform_v1beta1/types/pipeline_service.py +++ b/google/cloud/aiplatform_v1beta1/types/pipeline_service.py @@ -229,6 +229,7 @@ class ListPipelineJobsRequest(proto.Message): comparisons, and ``:`` wildcard. for example, can check if pipeline's display_name contains *step* by doing display_name:"*step*" + - ``state``: Supports ``=`` and ``!=`` comparisons. - ``create_time``: Supports ``=``, ``!=``, ``<``, ``>``, ``<=``, and ``>=`` comparisons. Values must be in RFC 3339 format. @@ -278,6 +279,7 @@ class ListPipelineJobsRequest(proto.Message): - ``create_time`` - ``update_time`` - ``end_time`` + - ``start_time`` """ parent = proto.Field(proto.STRING, number=1,) diff --git a/google/cloud/aiplatform_v1beta1/types/prediction_service.py b/google/cloud/aiplatform_v1beta1/types/prediction_service.py index 4b258f6fa6..45c6ac3206 100644 --- a/google/cloud/aiplatform_v1beta1/types/prediction_service.py +++ b/google/cloud/aiplatform_v1beta1/types/prediction_service.py @@ -83,14 +83,14 @@ class PredictResponse(proto.Message): ID of the Endpoint's DeployedModel that served this prediction. model (str): - Output only. The name of the Model this - DeployedModel, that served this prediction, was - created from. + Output only. The resource name of the Model + which is deployed as the DeployedModel that this + prediction hits. model_display_name (str): Output only. The [display name][google.cloud.aiplatform.v1beta1.Model.display_name] of - the Model this DeployedModel, that served this prediction, - was created from. + the Model which is deployed as the DeployedModel that this + prediction hits. """ predictions = proto.RepeatedField( diff --git a/google/cloud/aiplatform_v1beta1/types/study.py b/google/cloud/aiplatform_v1beta1/types/study.py index f847b9bbad..77032803f9 100644 --- a/google/cloud/aiplatform_v1beta1/types/study.py +++ b/google/cloud/aiplatform_v1beta1/types/study.py @@ -27,7 +27,8 @@ class Study(proto.Message): - r"""A message representing a Study. + r"""LINT.IfChange + A message representing a Study. Attributes: name (str): @@ -97,13 +98,14 @@ class Trial(proto.Message): client_id (str): Output only. The identifier of the client that originally requested this Trial. Each client is identified by a unique - client_id. When a client asks for a suggestion, Vizier will - assign it a Trial. The client should evaluate the Trial, - complete it, and report back to Vizier. If suggestion is - asked again by same client_id before the Trial is completed, - the same Trial will be returned. Multiple clients with - different client_ids can ask for suggestions simultaneously, - each of them will get their own Trial. + client_id. When a client asks for a suggestion, Vertex AI + Vizier will assign it a Trial. The client should evaluate + the Trial, complete it, and report back to Vertex AI Vizier. + If suggestion is asked again by same client_id before the + Trial is completed, the same Trial will be returned. + Multiple clients with different client_ids can ask for + suggestions simultaneously, each of them will get their own + Trial. infeasible_reason (str): Output only. A human readable string describing why the Trial is infeasible. This is set only if Trial state is @@ -187,15 +189,18 @@ class StudySpec(proto.Message): decay_curve_stopping_spec (google.cloud.aiplatform_v1beta1.types.StudySpec.DecayCurveAutomatedStoppingSpec): The automated early stopping spec using decay curve rule. + This field is a member of `oneof`_ ``automated_stopping_spec``. median_automated_stopping_spec (google.cloud.aiplatform_v1beta1.types.StudySpec.MedianAutomatedStoppingSpec): The automated early stopping spec using median rule. + This field is a member of `oneof`_ ``automated_stopping_spec``. convex_stop_config (google.cloud.aiplatform_v1beta1.types.StudySpec.ConvexStopConfig): Deprecated. The automated early stopping using convex stopping rule. + This field is a member of `oneof`_ ``automated_stopping_spec``. metrics (Sequence[google.cloud.aiplatform_v1beta1.types.StudySpec.MetricSpec]): Required. Metric specs for the Study. @@ -205,9 +210,9 @@ class StudySpec(proto.Message): The search algorithm specified for the Study. observation_noise (google.cloud.aiplatform_v1beta1.types.StudySpec.ObservationNoise): The observation noise level of the study. - Currently only supported by the Vizier service. - Not supported by HyperparamterTuningJob or - TrainingPipeline. + Currently only supported by the Vertex AI Vizier + service. Not supported by HyperparamterTuningJob + or TrainingPipeline. measurement_selection_type (google.cloud.aiplatform_v1beta1.types.StudySpec.MeasurementSelectionType): Describe which measurement selection type will be used @@ -281,15 +286,19 @@ class ParameterSpec(proto.Message): Attributes: double_value_spec (google.cloud.aiplatform_v1beta1.types.StudySpec.ParameterSpec.DoubleValueSpec): The value spec for a 'DOUBLE' parameter. + This field is a member of `oneof`_ ``parameter_value_spec``. integer_value_spec (google.cloud.aiplatform_v1beta1.types.StudySpec.ParameterSpec.IntegerValueSpec): The value spec for an 'INTEGER' parameter. + This field is a member of `oneof`_ ``parameter_value_spec``. categorical_value_spec (google.cloud.aiplatform_v1beta1.types.StudySpec.ParameterSpec.CategoricalValueSpec): The value spec for a 'CATEGORICAL' parameter. + This field is a member of `oneof`_ ``parameter_value_spec``. discrete_value_spec (google.cloud.aiplatform_v1beta1.types.StudySpec.ParameterSpec.DiscreteValueSpec): The value spec for a 'DISCRETE' parameter. + This field is a member of `oneof`_ ``parameter_value_spec``. parameter_id (str): Required. The ID of the parameter. Must not @@ -328,8 +337,9 @@ class DoubleValueSpec(proto.Message): to be a relatively good starting point. Unset value signals that there is no offered starting point. - Currently only supported by the Vizier service. Not - supported by HyperparamterTuningJob or TrainingPipeline. + Currently only supported by the Vertex AI Vizier service. + Not supported by HyperparamterTuningJob or TrainingPipeline. + This field is a member of `oneof`_ ``_default_value``. """ @@ -352,8 +362,9 @@ class IntegerValueSpec(proto.Message): to be a relatively good starting point. Unset value signals that there is no offered starting point. - Currently only supported by the Vizier service. Not - supported by HyperparamterTuningJob or TrainingPipeline. + Currently only supported by the Vertex AI Vizier service. + Not supported by HyperparamterTuningJob or TrainingPipeline. + This field is a member of `oneof`_ ``_default_value``. """ @@ -374,6 +385,7 @@ class CategoricalValueSpec(proto.Message): Currently only supported by the Vizier service. Not supported by HyperparamterTuningJob or TrainingPipeline. + This field is a member of `oneof`_ ``_default_value``. """ @@ -399,6 +411,7 @@ class DiscreteValueSpec(proto.Message): Currently only supported by the Vizier service. Not supported by HyperparamterTuningJob or TrainingPipeline. + This field is a member of `oneof`_ ``_default_value``. """ @@ -420,14 +433,17 @@ class ConditionalParameterSpec(proto.Message): parent_discrete_values (google.cloud.aiplatform_v1beta1.types.StudySpec.ParameterSpec.ConditionalParameterSpec.DiscreteValueCondition): The spec for matching values from a parent parameter of ``DISCRETE`` type. + This field is a member of `oneof`_ ``parent_value_condition``. parent_int_values (google.cloud.aiplatform_v1beta1.types.StudySpec.ParameterSpec.ConditionalParameterSpec.IntValueCondition): The spec for matching values from a parent parameter of ``INTEGER`` type. + This field is a member of `oneof`_ ``parent_value_condition``. parent_categorical_values (google.cloud.aiplatform_v1beta1.types.StudySpec.ParameterSpec.ConditionalParameterSpec.CategoricalValueCondition): The spec for matching values from a parent parameter of ``CATEGORICAL`` type. + This field is a member of `oneof`_ ``parent_value_condition``. parameter_spec (google.cloud.aiplatform_v1beta1.types.StudySpec.ParameterSpec): Required. The spec for a conditional diff --git a/google/cloud/aiplatform_v1beta1/types/tensorboard_data.py b/google/cloud/aiplatform_v1beta1/types/tensorboard_data.py index 5612c7534d..59ae6ead8c 100644 --- a/google/cloud/aiplatform_v1beta1/types/tensorboard_data.py +++ b/google/cloud/aiplatform_v1beta1/types/tensorboard_data.py @@ -73,12 +73,15 @@ class TimeSeriesDataPoint(proto.Message): Attributes: scalar (google.cloud.aiplatform_v1beta1.types.Scalar): A scalar value. + This field is a member of `oneof`_ ``value``. tensor (google.cloud.aiplatform_v1beta1.types.TensorboardTensor): A tensor value. + This field is a member of `oneof`_ ``value``. blobs (google.cloud.aiplatform_v1beta1.types.TensorboardBlobSequence): A blob sequence value. + This field is a member of `oneof`_ ``value``. wall_time (google.protobuf.timestamp_pb2.Timestamp): Wall clock timestamp when this data point is diff --git a/google/cloud/aiplatform_v1beta1/types/training_pipeline.py b/google/cloud/aiplatform_v1beta1/types/training_pipeline.py index fca59156cb..6b9ee8c4dc 100644 --- a/google/cloud/aiplatform_v1beta1/types/training_pipeline.py +++ b/google/cloud/aiplatform_v1beta1/types/training_pipeline.py @@ -33,6 +33,7 @@ "FilterSplit", "PredefinedSplit", "TimestampSplit", + "StratifiedSplit", }, ) @@ -190,19 +191,29 @@ class InputDataConfig(proto.Message): fraction_split (google.cloud.aiplatform_v1beta1.types.FractionSplit): Split based on fractions defining the size of each set. + This field is a member of `oneof`_ ``split``. filter_split (google.cloud.aiplatform_v1beta1.types.FilterSplit): Split based on the provided filters for each set. + This field is a member of `oneof`_ ``split``. predefined_split (google.cloud.aiplatform_v1beta1.types.PredefinedSplit): Supported only for tabular Datasets. Split based on a predefined key. + This field is a member of `oneof`_ ``split``. timestamp_split (google.cloud.aiplatform_v1beta1.types.TimestampSplit): Supported only for tabular Datasets. Split based on the timestamp of the input data pieces. + + This field is a member of `oneof`_ ``split``. + stratified_split (google.cloud.aiplatform_v1beta1.types.StratifiedSplit): + Supported only for tabular Datasets. + Split based on the distribution of the specified + column. + This field is a member of `oneof`_ ``split``. gcs_destination (google.cloud.aiplatform_v1beta1.types.GcsDestination): The Cloud Storage location where the training data is to be @@ -229,6 +240,7 @@ class InputDataConfig(proto.Message): - AIP_TEST_DATA_URI = "gcs_destination/dataset---/test-*.${AIP_DATA_FORMAT}". + This field is a member of `oneof`_ ``destination``. bigquery_destination (google.cloud.aiplatform_v1beta1.types.BigQueryDestination): Only applicable to custom training with tabular Dataset with @@ -253,6 +265,7 @@ class InputDataConfig(proto.Message): - AIP_TEST_DATA_URI = "bigquery_destination.dataset\_\ **\ .test". + This field is a member of `oneof`_ ``destination``. dataset_id (str): Required. The ID of the Dataset in the same Project and @@ -317,6 +330,9 @@ class InputDataConfig(proto.Message): timestamp_split = proto.Field( proto.MESSAGE, number=5, oneof="split", message="TimestampSplit", ) + stratified_split = proto.Field( + proto.MESSAGE, number=12, oneof="split", message="StratifiedSplit", + ) gcs_destination = proto.Field( proto.MESSAGE, number=8, oneof="destination", message=io.GcsDestination, ) @@ -451,4 +467,45 @@ class TimestampSplit(proto.Message): key = proto.Field(proto.STRING, number=4,) +class StratifiedSplit(proto.Message): + r"""Assigns input data to the training, validation, and test sets so + that the distribution of values found in the categorical column (as + specified by the ``key`` field) is mirrored within each split. The + fraction values determine the relative sizes of the splits. + + For example, if the specified column has three values, with 50% of + the rows having value "A", 25% value "B", and 25% value "C", and the + split fractions are specified as 80/10/10, then the training set + will constitute 80% of the training data, with about 50% of the + training set rows having the value "A" for the specified column, + about 25% having the value "B", and about 25% having the value "C". + + Only the top 500 occurring values are used; any values not in the + top 500 values are randomly assigned to a split. If less than three + rows contain a specific value, those rows are randomly assigned. + + Supported only for tabular Datasets. + + Attributes: + training_fraction (float): + The fraction of the input data that is to be + used to train the Model. + validation_fraction (float): + The fraction of the input data that is to be + used to validate the Model. + test_fraction (float): + The fraction of the input data that is to be + used to evaluate the Model. + key (str): + Required. The key is a name of one of the + Dataset's data columns. The key provided must be + for a categorical column. + """ + + training_fraction = proto.Field(proto.DOUBLE, number=1,) + validation_fraction = proto.Field(proto.DOUBLE, number=2,) + test_fraction = proto.Field(proto.DOUBLE, number=3,) + key = proto.Field(proto.STRING, number=4,) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1beta1/types/unmanaged_container_model.py b/google/cloud/aiplatform_v1beta1/types/unmanaged_container_model.py new file mode 100644 index 0000000000..42ecf09fae --- /dev/null +++ b/google/cloud/aiplatform_v1beta1/types/unmanaged_container_model.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + +from google.cloud.aiplatform_v1beta1.types import model + + +__protobuf__ = proto.module( + package="google.cloud.aiplatform.v1beta1", manifest={"UnmanagedContainerModel",}, +) + + +class UnmanagedContainerModel(proto.Message): + r"""Contains model information necessary to perform batch + prediction without requiring a full model import. + + Attributes: + artifact_uri (str): + The path to the directory containing the + Model artifact and any of its supporting files. + predict_schemata (google.cloud.aiplatform_v1beta1.types.PredictSchemata): + Contains the schemata used in Model's + predictions and explanations + container_spec (google.cloud.aiplatform_v1beta1.types.ModelContainerSpec): + Input only. The specification of the + container that is to be used when deploying this + Model. + """ + + artifact_uri = proto.Field(proto.STRING, number=1,) + predict_schemata = proto.Field( + proto.MESSAGE, number=2, message=model.PredictSchemata, + ) + container_spec = proto.Field( + proto.MESSAGE, number=3, message=model.ModelContainerSpec, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/aiplatform_v1beta1/types/user_action_reference.py b/google/cloud/aiplatform_v1beta1/types/user_action_reference.py index 078c3d735d..5ecec5711f 100644 --- a/google/cloud/aiplatform_v1beta1/types/user_action_reference.py +++ b/google/cloud/aiplatform_v1beta1/types/user_action_reference.py @@ -39,11 +39,13 @@ class UserActionReference(proto.Message): operation. Resource name of the long running operation. Format: 'projects/{project}/locations/{location}/operations/{operation}' + This field is a member of `oneof`_ ``reference``. data_labeling_job (str): For API calls that start a LabelingJob. Resource name of the LabelingJob. Format: 'projects/{project}/locations/{location}/dataLabelingJobs/{data_labeling_job}' + This field is a member of `oneof`_ ``reference``. method (str): The method name of the API RPC call. For diff --git a/google/cloud/aiplatform_v1beta1/types/value.py b/google/cloud/aiplatform_v1beta1/types/value.py index 244c914f98..ac749b6746 100644 --- a/google/cloud/aiplatform_v1beta1/types/value.py +++ b/google/cloud/aiplatform_v1beta1/types/value.py @@ -34,12 +34,15 @@ class Value(proto.Message): Attributes: int_value (int): An integer value. + This field is a member of `oneof`_ ``value``. double_value (float): A double value. + This field is a member of `oneof`_ ``value``. string_value (str): A string value. + This field is a member of `oneof`_ ``value``. """ diff --git a/samples/model-builder/create_and_import_dataset_tabular_bigquery_sample.py b/samples/model-builder/create_and_import_dataset_tabular_bigquery_sample.py index b7f4ea8013..38328ab652 100644 --- a/samples/model-builder/create_and_import_dataset_tabular_bigquery_sample.py +++ b/samples/model-builder/create_and_import_dataset_tabular_bigquery_sample.py @@ -18,13 +18,13 @@ # [START aiplatform_sdk_create_and_import_dataset_tabular_bigquery_sample] def create_and_import_dataset_tabular_bigquery_sample( - display_name: str, project: str, location: str, bigquery_source: str, + display_name: str, project: str, location: str, bq_source: str, ): aiplatform.init(project=project, location=location) dataset = aiplatform.TabularDataset.create( - display_name=display_name, bigquery_source=bigquery_source, + display_name=display_name, bq_source=bq_source, ) dataset.wait() diff --git a/samples/model-builder/create_and_import_dataset_tabular_bigquery_sample_test.py b/samples/model-builder/create_and_import_dataset_tabular_bigquery_sample_test.py index 6eefcf7702..6917eee9cf 100644 --- a/samples/model-builder/create_and_import_dataset_tabular_bigquery_sample_test.py +++ b/samples/model-builder/create_and_import_dataset_tabular_bigquery_sample_test.py @@ -24,7 +24,7 @@ def test_create_and_import_dataset_tabular_bigquery_sample( create_and_import_dataset_tabular_bigquery_sample.create_and_import_dataset_tabular_bigquery_sample( project=constants.PROJECT, location=constants.LOCATION, - bigquery_source=constants.BIGQUERY_SOURCE, + bq_source=constants.BIGQUERY_SOURCE, display_name=constants.DISPLAY_NAME, ) @@ -32,5 +32,5 @@ def test_create_and_import_dataset_tabular_bigquery_sample( project=constants.PROJECT, location=constants.LOCATION ) mock_create_tabular_dataset.assert_called_once_with( - display_name=constants.DISPLAY_NAME, bigquery_source=constants.BIGQUERY_SOURCE, + display_name=constants.DISPLAY_NAME, bq_source=constants.BIGQUERY_SOURCE, ) diff --git a/samples/snippets/model_service/get_model_evaluation_image_classification_sample.py b/samples/snippets/model_service/get_model_evaluation_image_classification_sample.py index 9fe35aa60e..23e83e9239 100644 --- a/samples/snippets/model_service/get_model_evaluation_image_classification_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_image_classification_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_image_classification_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_image_object_detection_sample.py b/samples/snippets/model_service/get_model_evaluation_image_object_detection_sample.py index d6a4c5cc9a..d9d35b18b8 100644 --- a/samples/snippets/model_service/get_model_evaluation_image_object_detection_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_image_object_detection_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_image_object_detection_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_slice_sample.py b/samples/snippets/model_service/get_model_evaluation_slice_sample.py index e79e787c7d..f8a465ec95 100644 --- a/samples/snippets/model_service/get_model_evaluation_slice_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_slice_sample.py @@ -24,6 +24,19 @@ def get_model_evaluation_slice_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_tabular_classification_sample.py b/samples/snippets/model_service/get_model_evaluation_tabular_classification_sample.py index 2dd870f89f..e7c3901fb7 100644 --- a/samples/snippets/model_service/get_model_evaluation_tabular_classification_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_tabular_classification_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_tabular_classification_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_tabular_regression_sample.py b/samples/snippets/model_service/get_model_evaluation_tabular_regression_sample.py index b08bcd5a45..6923d16068 100644 --- a/samples/snippets/model_service/get_model_evaluation_tabular_regression_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_tabular_regression_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_tabular_regression_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_text_classification_sample.py b/samples/snippets/model_service/get_model_evaluation_text_classification_sample.py index cdaea5c988..300760a88d 100644 --- a/samples/snippets/model_service/get_model_evaluation_text_classification_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_text_classification_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_text_classification_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_text_entity_extraction_sample.py b/samples/snippets/model_service/get_model_evaluation_text_entity_extraction_sample.py index 1fff1fa767..9c43ba9279 100644 --- a/samples/snippets/model_service/get_model_evaluation_text_entity_extraction_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_text_entity_extraction_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_text_entity_extraction_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_text_sentiment_analysis_sample.py b/samples/snippets/model_service/get_model_evaluation_text_sentiment_analysis_sample.py index bb8521c1b1..65cbac6767 100644 --- a/samples/snippets/model_service/get_model_evaluation_text_sentiment_analysis_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_text_sentiment_analysis_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_text_sentiment_analysis_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_video_action_recognition_sample.py b/samples/snippets/model_service/get_model_evaluation_video_action_recognition_sample.py index 3233b45677..90e84b9ee9 100644 --- a/samples/snippets/model_service/get_model_evaluation_video_action_recognition_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_video_action_recognition_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_video_action_recognition_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_video_classification_sample.py b/samples/snippets/model_service/get_model_evaluation_video_classification_sample.py index 3f0eb65566..158e3ba1ff 100644 --- a/samples/snippets/model_service/get_model_evaluation_video_classification_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_video_classification_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_video_classification_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/get_model_evaluation_video_object_tracking_sample.py b/samples/snippets/model_service/get_model_evaluation_video_object_tracking_sample.py index 493b3730dd..2726681178 100644 --- a/samples/snippets/model_service/get_model_evaluation_video_object_tracking_sample.py +++ b/samples/snippets/model_service/get_model_evaluation_video_object_tracking_sample.py @@ -23,6 +23,19 @@ def get_model_evaluation_video_object_tracking_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/model_service/list_model_evaluation_slices_sample.py b/samples/snippets/model_service/list_model_evaluation_slices_sample.py index 8285999aca..1d895a41ce 100644 --- a/samples/snippets/model_service/list_model_evaluation_slices_sample.py +++ b/samples/snippets/model_service/list_model_evaluation_slices_sample.py @@ -23,6 +23,19 @@ def list_model_evaluation_slices_sample( location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + To obtain evaluation_id run the following commands where LOCATION + is the region where the model is stored, PROJECT is the project ID, + and MODEL_ID is the ID of your model. + + model_client = aiplatform.gapic.ModelServiceClient( + client_options={ + 'api_endpoint':'LOCATION-aiplatform.googleapis.com' + } + ) + evaluations = model_client.list_model_evaluations(parent='projects/PROJECT/locations/LOCATION/models/MODEL_ID') + print("evaluations:", evaluations) + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. diff --git a/samples/snippets/prediction_service/predict_custom_trained_model_sample.py b/samples/snippets/prediction_service/predict_custom_trained_model_sample.py index d48085945b..5d04fc2400 100644 --- a/samples/snippets/prediction_service/predict_custom_trained_model_sample.py +++ b/samples/snippets/prediction_service/predict_custom_trained_model_sample.py @@ -13,7 +13,7 @@ # limitations under the License. # [START aiplatform_predict_custom_trained_model_sample] -from typing import Dict +from typing import Dict, List, Union from google.cloud import aiplatform from google.protobuf import json_format @@ -23,18 +23,24 @@ def predict_custom_trained_model_sample( project: str, endpoint_id: str, - instance_dict: Dict, + instances: Union[Dict, List[Dict]], location: str = "us-central1", api_endpoint: str = "us-central1-aiplatform.googleapis.com", ): + """ + `instances` can be either single instance of type dict or a list + of instances. + """ # The AI Platform services require regional API endpoints. client_options = {"api_endpoint": api_endpoint} # Initialize client that will be used to create and send requests. # This client only needs to be created once, and can be reused for multiple requests. client = aiplatform.gapic.PredictionServiceClient(client_options=client_options) # The format of each instance should conform to the deployed model's prediction input schema. - instance = json_format.ParseDict(instance_dict, Value()) - instances = [instance] + instances = instances if type(instances) == list else [instances] + instances = [ + json_format.ParseDict(instance_dict, Value()) for instance_dict in instances + ] parameters_dict = {} parameters = json_format.ParseDict(parameters_dict, Value()) endpoint = client.endpoint_path( diff --git a/samples/snippets/prediction_service/predict_custom_trained_model_sample_test.py b/samples/snippets/prediction_service/predict_custom_trained_model_sample_test.py index b3cc1ddaf6..9ba69047c5 100644 --- a/samples/snippets/prediction_service/predict_custom_trained_model_sample_test.py +++ b/samples/snippets/prediction_service/predict_custom_trained_model_sample_test.py @@ -32,9 +32,20 @@ def test_ucaip_generated_predict_custom_trained_model_sample(capsys): instance_dict = {"image_bytes": {"b64": encoded_content}, "key": "0"} + # Single instance as a dict predict_custom_trained_model_sample.predict_custom_trained_model_sample( - instance_dict=instance_dict, project=PROJECT_ID, endpoint_id=ENDPOINT_ID + instances=instance_dict, project=PROJECT_ID, endpoint_id=ENDPOINT_ID + ) + + # Multiple instances in a list + predict_custom_trained_model_sample.predict_custom_trained_model_sample( + instances=[instance_dict, instance_dict], + project=PROJECT_ID, + endpoint_id=ENDPOINT_ID, ) out, _ = capsys.readouterr() assert "1.0" in out + + # Two sets of scores for multi-instance, one score for single instance + assert out.count("scores") == 3 diff --git a/setup.py b/setup.py index caa50df32c..4ef6968114 100644 --- a/setup.py +++ b/setup.py @@ -36,10 +36,18 @@ tensorboard_extra_require = ["tensorflow >=2.3.0, <=2.5.0"] metadata_extra_require = ["pandas >= 1.0.0"] xai_extra_require = ["tensorflow >=2.3.0, <=2.5.0"] +profiler_extra_require = [ + "tensorboard-plugin-profile >= 2.4.0", + "werkzeug >= 2.0.0", + "tensorflow >=2.4.0", +] + full_extra_require = list( set(tensorboard_extra_require + metadata_extra_require + xai_extra_require) ) -testing_extra_require = full_extra_require + ["grpcio-testing", "pytest-xdist"] +testing_extra_require = ( + full_extra_require + profiler_extra_require + ["grpcio-testing", "pytest-xdist"] +) setuptools.setup( @@ -80,6 +88,7 @@ "tensorboard": tensorboard_extra_require, "testing": testing_extra_require, "xai": xai_extra_require, + "cloud-profiler": profiler_extra_require, }, python_requires=">=3.6", scripts=[], diff --git a/tests/system/aiplatform/test_featurestore.py b/tests/system/aiplatform/test_featurestore.py new file mode 100644 index 0000000000..6107f826ec --- /dev/null +++ b/tests/system/aiplatform/test_featurestore.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +from google.cloud import aiplatform +from tests.system.aiplatform import e2e_base + + +class TestFeaturestore(e2e_base.TestEndToEnd): + + _temp_prefix = "temp-vertex-sdk-e2e-feature-store-test" + + def test_create_and_get_featurestore(self, shared_state): + + aiplatform.init( + project=e2e_base._PROJECT, location=e2e_base._LOCATION, + ) + + shared_state["resources"] = [] + + list_featurestores = aiplatform.Featurestore.list() + assert len(list_featurestores) >= 0 + + list_searched_features = aiplatform.Feature.search() + assert len(list_searched_features) >= 0 diff --git a/tests/system/aiplatform/test_model_upload.py b/tests/system/aiplatform/test_model_upload.py new file mode 100644 index 0000000000..35ae44da69 --- /dev/null +++ b/tests/system/aiplatform/test_model_upload.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import tempfile + +import pytest + +from google import auth as google_auth +from google.cloud import aiplatform +from google.cloud import storage + +from tests.system.aiplatform import e2e_base + +# TODO(vinnys): Replace with env var `BUILD_SPECIFIC_GCP_PROJECT` once supported +_, _TEST_PROJECT = google_auth.default() +_TEST_LOCATION = "us-central1" + +_XGBOOST_MODEL_URI = "gs://cloud-samples-data-us-central1/vertex-ai/google-cloud-aiplatform-ci-artifacts/models/iris_xgboost/model.bst" + + +@pytest.mark.usefixtures("delete_staging_bucket", "teardown") +class TestModel(e2e_base.TestEndToEnd): + _temp_prefix = f"{_TEST_PROJECT}-vertex-staging-{_TEST_LOCATION}" + + def test_upload_and_deploy_xgboost_model(self, shared_state): + """Upload XGBoost model from local file and deploy it for prediction.""" + + aiplatform.init(project=_TEST_PROJECT, location=_TEST_LOCATION) + + storage_client = storage.Client(project=_TEST_PROJECT) + model_blob = storage.Blob.from_string( + uri=_XGBOOST_MODEL_URI, client=storage_client + ) + model_path = tempfile.mktemp() + ".my_model.xgb" + model_blob.download_to_filename(filename=model_path) + + model = aiplatform.Model.upload_xgboost_model_file(model_file_path=model_path,) + shared_state["resources"] = [model] + + staging_bucket = storage.Blob.from_string( + uri=model.uri, client=storage_client + ).bucket + # Checking that the bucket is auto-generated + assert "-vertex-staging-" in staging_bucket.name + + shared_state["bucket"] = staging_bucket + + # Currently we need to explicitly specify machine type. + # See https://github.com/googleapis/python-aiplatform/issues/773 + endpoint = model.deploy(machine_type="n1-standard-2") + shared_state["resources"].append(endpoint) + predict_response = endpoint.predict(instances=[[0, 0, 0]]) + assert len(predict_response.predictions) == 1 diff --git a/tests/system/aiplatform/test_tensorboard.py b/tests/system/aiplatform/test_tensorboard.py new file mode 100644 index 0000000000..9ec8179ca5 --- /dev/null +++ b/tests/system/aiplatform/test_tensorboard.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +from google.cloud import aiplatform +from tests.system.aiplatform import e2e_base + + +class TestTensorboard(e2e_base.TestEndToEnd): + + _temp_prefix = "temp-vertex-sdk-e2e-test" + + def test_create_and_get_tensorboard(self, shared_state): + + aiplatform.init( + project=e2e_base._PROJECT, location=e2e_base._LOCATION, + ) + + display_name = self._make_display_name("tensorboard") + + tb = aiplatform.Tensorboard.create(display_name=display_name) + + shared_state["resources"] = [tb] + + get_tb = aiplatform.Tensorboard(tb.resource_name) + + assert tb.resource_name == get_tb.resource_name + + list_tb = aiplatform.Tensorboard.list() + + assert len(list_tb) > 0 diff --git a/tests/unit/aiplatform/test_cloud_profiler.py b/tests/unit/aiplatform/test_cloud_profiler.py new file mode 100644 index 0000000000..3cde7a1296 --- /dev/null +++ b/tests/unit/aiplatform/test_cloud_profiler.py @@ -0,0 +1,447 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +import importlib.util +import json +import sys +import threading +from typing import List, Optional + +import pytest +import unittest + +from unittest import mock +from werkzeug import wrappers +from werkzeug.test import EnvironBuilder + +from google.api_core import exceptions +from google.cloud import aiplatform +from google.cloud.aiplatform import training_utils +from google.cloud.aiplatform.tensorboard.plugins.tf_profiler import profile_uploader +from google.cloud.aiplatform.training_utils.cloud_profiler.plugins import base_plugin +from google.cloud.aiplatform.training_utils.cloud_profiler.plugins.tensorflow import ( + tf_profiler, +) +from google.cloud.aiplatform.training_utils.cloud_profiler.plugins.tensorflow.tf_profiler import ( + TFProfiler, +) +from google.cloud.aiplatform.training_utils.cloud_profiler.plugins.tensorflow import ( + tensorboard_api, +) +from google.cloud.aiplatform.training_utils.cloud_profiler import webserver +from google.cloud.aiplatform.training_utils.cloud_profiler import initializer + + +# Mock cluster specs from the training environment. +_CLUSTER_SPEC_VM = { + "cluster": {"chief": ["localhost:1234"]}, + "environment": "cloud", + "task": {"type": "chief", "index": 0}, +} + + +def _create_mock_plugin( + plugin_name: str = "test_plugin", routes: Optional[List] = ["/route1"] +): + mock_plugin = mock.Mock(spec=base_plugin.BasePlugin) + mock_plugin.can_initialize.return_value = True + mock_plugin.post_setup_check.return_value = True + mock_plugin.PLUGIN_NAME = plugin_name + + # Some mock routes to test number of times each has been called. + mock_routes = {} + for route in routes: + mock_routes[route] = mock.Mock() + + mock_plugin.get_routes.return_value = mock_routes + + # A call should just return the mock object itself. + mock_plugin.return_value = mock_plugin + + return mock_plugin + + +def _find_child_modules(root_module): + return [module for module in sys.modules.keys() if module.startswith(root_module)] + + +@pytest.fixture +def tf_profile_plugin_mock(): + """Mock the tensorboard profile plugin""" + import tensorboard_plugin_profile.profile_plugin + + with mock.patch.object( + tensorboard_plugin_profile.profile_plugin.ProfilePlugin, "capture_route" + ) as profile_mock: + profile_mock.return_value = ( + wrappers.BaseResponse( + json.dumps({"error": "some error"}), + content_type="application/json", + status=200, + ), + ) + yield profile_mock + + +@pytest.fixture +def tensorboard_api_mock(): + with mock.patch.object( + tensorboard_api, "create_profile_request_sender", + ) as sender_mock: + sender_mock.return_value = mock.Mock() + yield sender_mock + + +@pytest.fixture +def mock_api_environment_variables(): + with mock.patch.object(training_utils, "environment_variables") as mock_env: + mock_env.tensorboard_api_uri = "testuri" + mock_env.tensorboard_resource_name = ( + "projects/testproj/locations/us-central1/tensorboards/123" + ) + mock_env.cloud_ml_job_id = "test_job_id" + mock_env.tensorboard_log_dir = "gs://my_log_dir" + + yield mock_env + + +def setupProfilerEnvVars(): + tf_profiler.environment_variables.tf_profiler_port = "6009" + tf_profiler.environment_variables.tensorboard_log_dir = "tmp/" + tf_profiler.environment_variables.tensorboard_api_uri = "test_api_uri" + tf_profiler.environment_variables.tensorboard_resource_name = ( + "projects/123/region/us-central1/tensorboards/mytb" + ) + tf_profiler.environment_variables.cluster_spec = _CLUSTER_SPEC_VM + tf_profiler.environment_variables.cloud_ml_job_id = "myjob" + + +class TestProfilerPlugin(unittest.TestCase): + def setUp(self): + setupProfilerEnvVars() + + # Environment variable tests + def testCanInitializeProfilerPortUnset(self): + tf_profiler.environment_variables.tf_profiler_port = None + assert not TFProfiler.can_initialize() + + def testCanInitializeTBLogDirUnset(self): + tf_profiler.environment_variables.tensorboard_log_dir = None + assert not TFProfiler.can_initialize() + + def testCanInitializeTBAPIuriUnset(self): + tf_profiler.environment_variables.tensorboard_api_uri = None + assert not TFProfiler.can_initialize() + + def testCanInitializeTBResourceNameUnset(self): + tf_profiler.environment_variables.tensorboard_resource_name = None + assert not TFProfiler.can_initialize() + + def testCanInitializeJobIdUnset(self): + tf_profiler.environment_variables.cloud_ml_job_id = None + assert not TFProfiler.can_initialize() + + def testCanInitializeNoClusterSpec(self): + tf_profiler.environment_variables.cluster_spec = None + assert not TFProfiler.can_initialize() + + # Check tensorflow dependencies + def testCanInitializeTFInstalled(self): + orig_find_spec = importlib.util.find_spec + + def tf_import_mock(name, *args, **kwargs): + if name == "tensorflow": + return None + return orig_find_spec(name, *args, **kwargs) + + with mock.patch("importlib.util.find_spec", side_effect=tf_import_mock): + assert not TFProfiler.can_initialize() + + def testCanInitializeTFVersion(self): + import tensorflow + + with mock.patch.dict(tensorflow.__dict__, {"__version__": "1.2.3.4"}): + assert not TFProfiler.can_initialize() + + def testCanInitializeOldTFVersion(self): + import tensorflow + + with mock.patch.dict(tensorflow.__dict__, {"__version__": "2.3.0"}): + assert not TFProfiler.can_initialize() + + def testCanInitializeNoProfilePlugin(self): + orig_find_spec = importlib.util.find_spec + + def plugin_import_mock(name, *args, **kwargs): + if name == "tensorboard_plugin_profile": + return None + return orig_find_spec(name, *args, **kwargs) + + with mock.patch("importlib.util.find_spec", side_effect=plugin_import_mock): + assert not TFProfiler.can_initialize() + + def testCanInitialize(self): + assert TFProfiler.can_initialize() + + def testSetup(self): + import tensorflow + + with mock.patch.object( + tensorflow.profiler.experimental.server, "start", return_value=None + ) as server_mock: + TFProfiler.setup() + + assert server_mock.call_count == 1 + + def testPostSetupChecksFail(self): + tf_profiler.environment_variables.cluster_spec = {} + assert not TFProfiler.post_setup_check() + + def testPostSetupChecks(self): + assert TFProfiler.post_setup_check() + + # Tests for plugin + @pytest.mark.usefixtures("tf_profile_plugin_mock") + @pytest.mark.usefixtures("tensorboard_api_mock") + def testCaptureProfile(self): + profiler = TFProfiler() + environ = dict(QUERY_STRING="?service_addr=myhost1,myhost2&someotherdata=5") + start_response = None + + resp = profiler.capture_profile_wrapper(environ, start_response) + assert resp[0].status_code == 200 + + @pytest.mark.usefixtures("tf_profile_plugin_mock") + @pytest.mark.usefixtures("tensorboard_api_mock") + def testCaptureProfileNoClusterSpec(self): + profiler = TFProfiler() + + environ = dict(QUERY_STRING="?service_addr=myhost1,myhost2&someotherdata=5") + start_response = None + + tf_profiler.environment_variables.cluster_spec = None + resp = profiler.capture_profile_wrapper(environ, start_response) + + assert resp.status_code == 500 + + @pytest.mark.usefixtures("tf_profile_plugin_mock") + @pytest.mark.usefixtures("tensorboard_api_mock") + def testCaptureProfileNoCluster(self): + profiler = TFProfiler() + + environ = dict(QUERY_STRING="?service_addr=myhost1,myhost2&someotherdata=5") + start_response = None + tf_profiler.environment_variables.cluster_spec = {"cluster": {}} + + resp = profiler.capture_profile_wrapper(environ, start_response) + + assert resp.status_code == 500 + + @pytest.mark.usefixtures("tf_profile_plugin_mock") + @pytest.mark.usefixtures("tensorboard_api_mock") + def testGetRoutes(self): + profiler = TFProfiler() + + routes = profiler.get_routes() + assert isinstance(routes, dict) + + +# Tensorboard API tests +class TestTensorboardAPIBuilder(unittest.TestCase): + @pytest.mark.usefixtures("mock_api_environment_variables") + def test_get_api_client(self): + with mock.patch.object(aiplatform, "initializer") as mock_initializer: + tensorboard_api._get_api_client() + mock_initializer.global_config.create_client.assert_called_once() + + def test_get_project_id_fail(self): + with mock.patch.object(training_utils, "environment_variables") as mock_env: + mock_env.tensorboard_resource_name = "bad_resource" + self.assertRaises(ValueError, tensorboard_api._get_project_id) + + @pytest.mark.usefixtures("mock_api_environment_variables") + def test_get_project_id(self): + project_id = tensorboard_api._get_project_id() + assert project_id == "testproj" + + @pytest.mark.usefixtures("mock_api_environment_variables") + def test_get_or_create_experiment(self): + api = mock.Mock() + api.create_tensorboard_experiment.side_effect = exceptions.AlreadyExists("test") + tensorboard_api._get_or_create_experiment(api, "test") + api.get_tensorboard_experiment.assert_called_once() + + @pytest.mark.usefixtures("mock_api_environment_variables") + def test_create_profile_request_sender(self): + tensorboard_api.storage = mock.Mock() + tensorboard_api.uploader_utils = mock.Mock() + + with mock.patch.object(profile_uploader, "ProfileRequestSender") as mock_sender: + with mock.patch.object(aiplatform, "initializer"): + tensorboard_api.create_profile_request_sender() + mock_sender.assert_called_once() + + +# Webserver tests +class TestWebServer(unittest.TestCase): + def test_create_webserver_bad_route(self): + plugin = _create_mock_plugin() + plugin.get_routes.return_value = {"my_route": "some_handler"} + + self.assertRaises(ValueError, webserver.WebServer, [plugin]) + + def test_dispatch_bad_request(self): + plugin = _create_mock_plugin() + plugin.get_routes.return_value = {"/test_route": "test_handler"} + + ws = webserver.WebServer([plugin]) + + builder = EnvironBuilder(method="GET", path="/") + + env = builder.get_environ() + + # Mock a start response callable + response = [] + buff = [] + + def start_response(status, headers): + response[:] = [status, headers] + return buff.append + + ws(env, start_response) + + assert response[0] == "404 NOT FOUND" + + def test_correct_response(self): + res_dict = {"response": "OK"} + + def my_callable(var1, var2): + return wrappers.BaseResponse( + json.dumps(res_dict), content_type="application/json", status=200 + ) + + plugin = _create_mock_plugin() + plugin.get_routes.return_value = {"/my_route": my_callable} + ws = webserver.WebServer([plugin]) + + builder = EnvironBuilder(method="GET", path="/test_plugin/my_route") + + env = builder.get_environ() + + # Mock a start response callable + response = [] + buff = [] + + def start_response(status, headers): + response[:] = [status, headers] + return buff.append + + res = ws(env, start_response) + + final_response = json.loads(res.response[0].decode("utf-8")) + + assert final_response == res_dict + + +# Initializer tests +class TestInitializer(unittest.TestCase): + def testImportError(self): + # Unloads any of the cloud profiler sub-modules + for mod in _find_child_modules( + "google.cloud.aiplatform.training_utils.cloud_profiler" + ): + del sys.modules[mod] + + # Modules to be mocked out + for mock_module in [ + "tensorflow", + "tensorboard_plugin_profile.profile_plugin", + "werkzeug", + ]: + with self.subTest(): + with mock.patch.dict("sys.modules", {mock_module: None}): + with self.assertRaises(ImportError) as cm: + importlib.import_module( + "google.cloud.aiplatform.training_utils.cloud_profiler" + ) + assert "Could not load the cloud profiler" in cm.exception.msg + + def test_build_plugin_fail_initialize(self): + plugin = _create_mock_plugin() + plugin.can_initialize.return_value = False + + assert not initializer._build_plugin(plugin) + + def test_build_plugin_fail_setup_check(self): + plugin = _create_mock_plugin() + plugin.can_initialize.return_value = True + plugin.post_setup_check.return_value = False + + assert not initializer._build_plugin(plugin) + + def test_build_plugin_success(self): + plugin = _create_mock_plugin() + plugin.can_initialize.return_value = True + plugin.post_setup_check.return_value = True + + initializer._build_plugin(plugin) + + assert plugin.called + + # Testing the initialize function + def test_initialize_bad_plugin(self): + with mock.patch.object(initializer, "_AVAILABLE_PLUGINS", {}): + self.assertRaises(ValueError, initializer.initialize, "bad_plugin") + + def test_initialize_build_plugin_fail(self): + plugin = _create_mock_plugin() + with mock.patch.object(initializer, "_AVAILABLE_PLUGINS", {"test": plugin}): + with mock.patch.object(initializer, "_build_plugin") as build_mock: + with mock.patch.object( + initializer, "_run_app_thread" + ) as app_thread_mock: + build_mock.return_value = None + initializer.initialize("test") + + assert not app_thread_mock.call_count + + def test_initialize_no_http_handler(self): + plugin = _create_mock_plugin() + initializer.environment_variables.http_handler_port = None + + with mock.patch.object(initializer, "_AVAILABLE_PLUGINS", {"test": plugin}): + with pytest.raises(initializer.MissingEnvironmentVariableException): + initializer.initialize("test") + + def test_initialize_build_plugin_success(self): + plugin = _create_mock_plugin() + initializer.environment_variables.http_handler_port = "1234" + + with mock.patch.object(initializer, "_AVAILABLE_PLUGINS", {"test": plugin}): + with mock.patch.object(initializer, "_run_app_thread") as app_thread_mock: + initializer.initialize("test") + + assert app_thread_mock.call_count == 1 + + def test_run_app_thread(self): + with mock.patch.object(threading, "Thread") as mock_thread: + daemon_mock = mock.Mock() + mock_thread.return_value = daemon_mock + + initializer._run_app_thread(None, 1234) + + assert daemon_mock.start.call_count == 1 diff --git a/tests/unit/aiplatform/test_custom_job.py b/tests/unit/aiplatform/test_custom_job.py index ea362ecda8..f865385e7d 100644 --- a/tests/unit/aiplatform/test_custom_job.py +++ b/tests/unit/aiplatform/test_custom_job.py @@ -31,18 +31,12 @@ from google.cloud import aiplatform from google.cloud.aiplatform import base from google.cloud.aiplatform.compat.types import custom_job as gca_custom_job_compat -from google.cloud.aiplatform.compat.types import ( - custom_job_v1beta1 as gca_custom_job_v1beta1, -) from google.cloud.aiplatform.compat.types import io as gca_io_compat from google.cloud.aiplatform.compat.types import job_state as gca_job_state_compat from google.cloud.aiplatform.compat.types import ( encryption_spec as gca_encryption_spec_compat, ) from google.cloud.aiplatform_v1.services.job_service import client as job_service_client -from google.cloud.aiplatform_v1beta1.services.job_service import ( - client as job_service_client_v1beta1, -) _TEST_PROJECT = "test-project" _TEST_LOCATION = "us-central1" @@ -114,29 +108,16 @@ ) -def _get_custom_job_proto(state=None, name=None, error=None, version="v1"): +def _get_custom_job_proto(state=None, name=None, error=None): custom_job_proto = copy.deepcopy(_TEST_BASE_CUSTOM_JOB_PROTO) custom_job_proto.name = name custom_job_proto.state = state custom_job_proto.error = error - - if version == "v1beta1": - v1beta1_custom_job_proto = gca_custom_job_v1beta1.CustomJob() - v1beta1_custom_job_proto._pb.MergeFromString( - custom_job_proto._pb.SerializeToString() - ) - custom_job_proto = v1beta1_custom_job_proto - custom_job_proto.job_spec.tensorboard = _TEST_TENSORBOARD_NAME - return custom_job_proto -def _get_custom_job_proto_with_enable_web_access( - state=None, name=None, error=None, version="v1" -): - custom_job_proto = _get_custom_job_proto( - state=state, name=name, error=error, version=version - ) +def _get_custom_job_proto_with_enable_web_access(state=None, name=None, error=None): + custom_job_proto = _get_custom_job_proto(state=state, name=name, error=error) custom_job_proto.job_spec.enable_web_access = _TEST_ENABLE_WEB_ACCESS if state == gca_job_state_compat.JobState.JOB_STATE_RUNNING: custom_job_proto.web_access_uris = _TEST_WEB_ACCESS_URIS @@ -260,24 +241,25 @@ def create_custom_job_mock_with_enable_web_access(): @pytest.fixture -def create_custom_job_mock_fail(): +def create_custom_job_mock_with_tensorboard(): with mock.patch.object( job_service_client.JobServiceClient, "create_custom_job" ) as create_custom_job_mock: - create_custom_job_mock.side_effect = RuntimeError("Mock fail") + custom_job_proto = _get_custom_job_proto( + name=_TEST_CUSTOM_JOB_NAME, + state=gca_job_state_compat.JobState.JOB_STATE_PENDING, + ) + custom_job_proto.job_spec.tensorboard = _TEST_TENSORBOARD_NAME + create_custom_job_mock.return_value = custom_job_proto yield create_custom_job_mock @pytest.fixture -def create_custom_job_v1beta1_mock(): +def create_custom_job_mock_fail(): with mock.patch.object( - job_service_client_v1beta1.JobServiceClient, "create_custom_job" + job_service_client.JobServiceClient, "create_custom_job" ) as create_custom_job_mock: - create_custom_job_mock.return_value = _get_custom_job_proto( - name=_TEST_CUSTOM_JOB_NAME, - state=gca_job_state_compat.JobState.JOB_STATE_PENDING, - version="v1beta1", - ) + create_custom_job_mock.side_effect = RuntimeError("Mock fail") yield create_custom_job_mock @@ -573,7 +555,7 @@ def test_get_web_access_uris_job_succeeded( @pytest.mark.parametrize("sync", [True, False]) def test_create_custom_job_with_tensorboard( - self, create_custom_job_v1beta1_mock, get_custom_job_mock, sync + self, create_custom_job_mock_with_tensorboard, get_custom_job_mock, sync ): aiplatform.init( @@ -601,9 +583,10 @@ def test_create_custom_job_with_tensorboard( job.wait() - expected_custom_job = _get_custom_job_proto(version="v1beta1") + expected_custom_job = _get_custom_job_proto() + expected_custom_job.job_spec.tensorboard = _TEST_TENSORBOARD_NAME - create_custom_job_v1beta1_mock.assert_called_once_with( + create_custom_job_mock_with_tensorboard.assert_called_once_with( parent=_TEST_PARENT, custom_job=expected_custom_job ) diff --git a/tests/unit/aiplatform/test_datasets.py b/tests/unit/aiplatform/test_datasets.py index f80beac240..71ca5907ab 100644 --- a/tests/unit/aiplatform/test_datasets.py +++ b/tests/unit/aiplatform/test_datasets.py @@ -30,6 +30,7 @@ from google.cloud import aiplatform from google.cloud.aiplatform import base from google.cloud.aiplatform import compat +from google.cloud.aiplatform.constants import base as constants from google.cloud.aiplatform import datasets from google.cloud.aiplatform import initializer from google.cloud.aiplatform import schema @@ -514,7 +515,7 @@ def test_init_dataset_with_alt_location(self, get_dataset_tabular_gcs_mock): assert ( ds.api_client._clients[compat.DEFAULT_VERSION]._client_options.api_endpoint - == f"{_TEST_LOCATION}-{aiplatform.constants.API_BASE_PATH}" + == f"{_TEST_LOCATION}-{constants.API_BASE_PATH}" ) assert _TEST_ALT_LOCATION != _TEST_LOCATION diff --git a/tests/unit/aiplatform/test_featurestores.py b/tests/unit/aiplatform/test_featurestores.py new file mode 100644 index 0000000000..4cede4ba09 --- /dev/null +++ b/tests/unit/aiplatform/test_featurestores.py @@ -0,0 +1,719 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +import pytest + +from unittest import mock +from importlib import reload +from unittest.mock import patch + +from google.api_core import operation +from google.protobuf import field_mask_pb2 + +from google.cloud import aiplatform +from google.cloud.aiplatform import base +from google.cloud.aiplatform import initializer + +from google.cloud.aiplatform.utils import featurestore_utils + +from google.cloud.aiplatform_v1.services.featurestore_service import ( + client as featurestore_service_client, +) + +from google.cloud.aiplatform_v1.types import ( + featurestore as gca_featurestore, + entity_type as gca_entity_type, + feature as gca_feature, + encryption_spec as gca_encryption_spec, +) + +# project +_TEST_PROJECT = "test-project" +_TEST_LOCATION = "us-central1" +_TEST_PARENT = f"projects/{_TEST_PROJECT}/locations/{_TEST_LOCATION}" + +# featurestore +_TEST_FEATURESTORE_ID = "featurestore_id" +_TEST_FEATURESTORE_NAME = f"{_TEST_PARENT}/featurestores/{_TEST_FEATURESTORE_ID}" +_TEST_FEATURESTORE_INVALID = f"{_TEST_PARENT}/featurestore/{_TEST_FEATURESTORE_ID}" + +# featurestore online +_TEST_ONLINE_SERVING_CONFIG = 1 +_TEST_ONLINE_SERVING_CONFIG_UPDATE = 2 + +# entity_type +_TEST_ENTITY_TYPE_ID = "entity_type_id" +_TEST_ENTITY_TYPE_NAME = f"{_TEST_FEATURESTORE_NAME}/entityTypes/{_TEST_ENTITY_TYPE_ID}" +_TEST_ENTITY_TYPE_INVALID = ( + f"{_TEST_FEATURESTORE_NAME}/entityType/{_TEST_ENTITY_TYPE_ID}" +) + +# feature +_TEST_FEATURE_ID = "feature_id" +_TEST_FEATURE_NAME = f"{_TEST_ENTITY_TYPE_NAME}/features/{_TEST_FEATURE_ID}" +_TEST_FEATURE_INVALID = f"{_TEST_ENTITY_TYPE_NAME}/feature/{_TEST_FEATURE_ID}" + +# misc +_TEST_DESCRIPTION = "my description" +_TEST_LABELS = {"my_key": "my_value"} +_TEST_DESCRIPTION_UPDATE = "my description update" +_TEST_LABELS_UPDATE = {"my_key_update": "my_value_update"} + +# request_metadata +_TEST_REQUEST_METADATA = () + +# CMEK encryption +_TEST_ENCRYPTION_KEY_NAME = "key_1234" +_TEST_ENCRYPTION_SPEC = gca_encryption_spec.EncryptionSpec( + kms_key_name=_TEST_ENCRYPTION_KEY_NAME +) + +# Lists +_TEST_FEATURESTORE_LIST = [ + gca_featurestore.Featurestore( + name=_TEST_FEATURESTORE_NAME, + online_serving_config=gca_featurestore.Featurestore.OnlineServingConfig( + fixed_node_count=_TEST_ONLINE_SERVING_CONFIG + ), + encryption_spec=_TEST_ENCRYPTION_SPEC, + ), + gca_featurestore.Featurestore( + name=_TEST_FEATURESTORE_NAME, + online_serving_config=gca_featurestore.Featurestore.OnlineServingConfig( + fixed_node_count=_TEST_ONLINE_SERVING_CONFIG + ), + ), + gca_featurestore.Featurestore( + name=_TEST_FEATURESTORE_NAME, + online_serving_config=gca_featurestore.Featurestore.OnlineServingConfig( + fixed_node_count=_TEST_ONLINE_SERVING_CONFIG + ), + encryption_spec=_TEST_ENCRYPTION_SPEC, + ), +] + +_TEST_ENTITY_TYPE_LIST = [ + gca_entity_type.EntityType(name=_TEST_ENTITY_TYPE_NAME,), + gca_entity_type.EntityType(name=_TEST_ENTITY_TYPE_NAME,), + gca_entity_type.EntityType(name=_TEST_ENTITY_TYPE_NAME,), +] + +_TEST_FEATURE_LIST = [ + gca_feature.Feature(name=_TEST_FEATURE_NAME,), + gca_feature.Feature(name=_TEST_FEATURE_NAME,), + gca_feature.Feature(name=_TEST_FEATURE_NAME,), +] + + +# All Featurestore Mocks +@pytest.fixture +def get_featurestore_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "get_featurestore" + ) as get_featurestore_mock: + get_featurestore_mock.return_value = gca_featurestore.Featurestore( + name=_TEST_FEATURESTORE_NAME, + online_serving_config=gca_featurestore.Featurestore.OnlineServingConfig( + fixed_node_count=_TEST_ONLINE_SERVING_CONFIG + ), + encryption_spec=_TEST_ENCRYPTION_SPEC, + ) + yield get_featurestore_mock + + +@pytest.fixture +def update_featurestore_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "update_featurestore" + ) as update_featurestore_mock: + update_featurestore_lro_mock = mock.Mock(operation.Operation) + update_featurestore_mock.return_value = update_featurestore_lro_mock + yield update_featurestore_mock + + +@pytest.fixture +def list_featurestores_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "list_featurestores" + ) as list_featurestores_mock: + list_featurestores_mock.return_value = _TEST_FEATURESTORE_LIST + yield list_featurestores_mock + + +@pytest.fixture +def delete_featurestore_mock(): + with mock.patch.object( + featurestore_service_client.FeaturestoreServiceClient, "delete_featurestore" + ) as delete_featurestore_mock: + delete_featurestore_lro_mock = mock.Mock(operation.Operation) + delete_featurestore_mock.return_value = delete_featurestore_lro_mock + yield delete_featurestore_mock + + +@pytest.fixture +def search_features_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "search_features" + ) as search_features_mock: + search_features_mock.return_value = _TEST_FEATURE_LIST + yield search_features_mock + + +# ALL EntityType Mocks +@pytest.fixture +def get_entity_type_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "get_entity_type" + ) as get_entity_type_mock: + get_entity_type_mock.return_value = gca_entity_type.EntityType( + name=_TEST_ENTITY_TYPE_NAME, + ) + yield get_entity_type_mock + + +@pytest.fixture +def update_entity_type_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "update_entity_type" + ) as update_entity_type_mock: + update_entity_type_lro_mock = mock.Mock(operation.Operation) + update_entity_type_mock.return_value = update_entity_type_lro_mock + yield update_entity_type_mock + + +@pytest.fixture +def list_entity_types_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "list_entity_types" + ) as list_entity_types_mock: + list_entity_types_mock.return_value = _TEST_ENTITY_TYPE_LIST + yield list_entity_types_mock + + +@pytest.fixture +def delete_entity_type_mock(): + with mock.patch.object( + featurestore_service_client.FeaturestoreServiceClient, "delete_entity_type" + ) as delete_entity_type_mock: + delete_entity_type_lro_mock = mock.Mock(operation.Operation) + delete_entity_type_mock.return_value = delete_entity_type_lro_mock + yield delete_entity_type_mock + + +# ALL Feature Mocks +@pytest.fixture +def get_feature_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "get_feature" + ) as get_feature_mock: + get_feature_mock.return_value = gca_feature.Feature(name=_TEST_FEATURE_NAME,) + yield get_feature_mock + + +@pytest.fixture +def update_feature_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "update_feature" + ) as update_feature_mock: + update_feature_lro_mock = mock.Mock(operation.Operation) + update_feature_mock.return_value = update_feature_lro_mock + yield update_feature_mock + + +@pytest.fixture +def list_features_mock(): + with patch.object( + featurestore_service_client.FeaturestoreServiceClient, "list_features" + ) as list_features_mock: + list_features_mock.return_value = _TEST_FEATURE_LIST + yield list_features_mock + + +@pytest.fixture +def delete_feature_mock(): + with mock.patch.object( + featurestore_service_client.FeaturestoreServiceClient, "delete_feature" + ) as delete_feature_mock: + delete_feature_lro_mock = mock.Mock(operation.Operation) + delete_feature_mock.return_value = delete_feature_lro_mock + yield delete_feature_mock + + +class TestFeaturestoreUtils: + @pytest.mark.parametrize( + "resource_id, expected", + [ + ("resource_id", True), + ("resource_id12345", True), + ("12345resource_id", False), + ("_resource_id", True), + ("resource_id/1234", False), + ("_resource_id/1234", False), + ("resource-id-1234", False), + ("123456", False), + ("c" * 61, False), + ("_123456", True), + ], + ) + def test_validate_resource_id(self, resource_id: str, expected: bool): + assert expected == featurestore_utils.validate_id(resource_id) + + @pytest.mark.parametrize( + "feature_name, featurestore_id, entity_type_id", + [ + (_TEST_FEATURE_NAME, None, None,), + (_TEST_FEATURE_ID, _TEST_FEATURESTORE_ID, _TEST_ENTITY_TYPE_ID,), + ], + ) + def test_validate_and_get_feature_resource_ids( + self, feature_name: str, featurestore_id: str, entity_type_id: str, + ): + assert ( + _TEST_FEATURESTORE_ID, + _TEST_ENTITY_TYPE_ID, + _TEST_FEATURE_ID, + ) == featurestore_utils.validate_and_get_feature_resource_ids( + feature_name=feature_name, + featurestore_id=featurestore_id, + entity_type_id=entity_type_id, + ) + + @pytest.mark.parametrize( + "feature_name, featurestore_id, entity_type_id", + [ + (_TEST_FEATURE_INVALID, None, None,), + (_TEST_FEATURE_ID, None, _TEST_ENTITY_TYPE_ID,), + (_TEST_FEATURE_ID, None, None,), + (_TEST_FEATURE_ID, _TEST_FEATURESTORE_NAME, None,), + ], + ) + def test_validate_and_get_feature_resource_ids_with_raise( + self, feature_name: str, featurestore_id: str, entity_type_id: str, + ): + with pytest.raises(ValueError): + featurestore_utils.validate_and_get_feature_resource_ids( + feature_name=feature_name, + featurestore_id=featurestore_id, + entity_type_id=entity_type_id, + ) + + @pytest.mark.parametrize( + "entity_type_name, featurestore_id", + [ + (_TEST_ENTITY_TYPE_NAME, None,), + (_TEST_ENTITY_TYPE_ID, _TEST_FEATURESTORE_ID,), + ], + ) + def test_validate_and_get_entity_type_resource_ids( + self, entity_type_name: str, featurestore_id: str + ): + assert ( + _TEST_FEATURESTORE_ID, + _TEST_ENTITY_TYPE_ID, + ) == featurestore_utils.validate_and_get_entity_type_resource_ids( + entity_type_name=entity_type_name, featurestore_id=featurestore_id + ) + + @pytest.mark.parametrize( + "entity_type_name, featurestore_id", + [ + (_TEST_ENTITY_TYPE_INVALID, None,), + (_TEST_ENTITY_TYPE_ID, None,), + (_TEST_ENTITY_TYPE_ID, _TEST_FEATURESTORE_NAME,), + ], + ) + def test_validate_and_get_entity_type_resource_ids_with_raise( + self, entity_type_name: str, featurestore_id: str, + ): + with pytest.raises(ValueError): + featurestore_utils.validate_and_get_entity_type_resource_ids( + entity_type_name=entity_type_name, featurestore_id=featurestore_id + ) + + +class TestFeaturestore: + def setup_method(self): + reload(initializer) + reload(aiplatform) + + def teardown_method(self): + initializer.global_pool.shutdown(wait=True) + + @pytest.mark.parametrize( + "featurestore_name", [_TEST_FEATURESTORE_ID, _TEST_FEATURESTORE_NAME] + ) + def test_init_featurestore(self, featurestore_name, get_featurestore_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_featurestore = aiplatform.Featurestore(featurestore_name=featurestore_name) + + get_featurestore_mock.assert_called_once_with( + name=my_featurestore.resource_name, retry=base._DEFAULT_RETRY + ) + + @pytest.mark.usefixtures("get_featurestore_mock") + def test_get_entity_type(self, get_entity_type_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_featurestore = aiplatform.Featurestore( + featurestore_name=_TEST_FEATURESTORE_ID + ) + my_entity_type = my_featurestore.get_entity_type( + entity_type_id=_TEST_ENTITY_TYPE_ID + ) + + get_entity_type_mock.assert_called_once_with( + name=_TEST_ENTITY_TYPE_NAME, retry=base._DEFAULT_RETRY + ) + assert type(my_entity_type) == aiplatform.EntityType + + @pytest.mark.usefixtures("get_featurestore_mock") + def test_update_featurestore(self, update_featurestore_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_featurestore = aiplatform.Featurestore( + featurestore_name=_TEST_FEATURESTORE_ID + ) + my_featurestore.update(labels=_TEST_LABELS_UPDATE) + + expected_featurestore = gca_featurestore.Featurestore( + name=_TEST_FEATURESTORE_NAME, + labels=_TEST_LABELS_UPDATE, + online_serving_config=gca_featurestore.Featurestore.OnlineServingConfig(), + ) + update_featurestore_mock.assert_called_once_with( + featurestore=expected_featurestore, + update_mask=field_mask_pb2.FieldMask(paths=["labels"]), + metadata=_TEST_REQUEST_METADATA, + ) + + @pytest.mark.usefixtures("get_featurestore_mock") + def test_update_featurestore_online(self, update_featurestore_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_featurestore = aiplatform.Featurestore( + featurestore_name=_TEST_FEATURESTORE_ID + ) + my_featurestore.update_online_store( + fixed_node_count=_TEST_ONLINE_SERVING_CONFIG_UPDATE + ) + + expected_featurestore = gca_featurestore.Featurestore( + name=_TEST_FEATURESTORE_NAME, + online_serving_config=gca_featurestore.Featurestore.OnlineServingConfig( + fixed_node_count=_TEST_ONLINE_SERVING_CONFIG_UPDATE + ), + ) + update_featurestore_mock.assert_called_once_with( + featurestore=expected_featurestore, + update_mask=field_mask_pb2.FieldMask( + paths=["online_serving_config.fixed_node_count"] + ), + metadata=_TEST_REQUEST_METADATA, + ) + + def test_list_featurestores(self, list_featurestores_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_featurestore_list = aiplatform.Featurestore.list() + + list_featurestores_mock.assert_called_once_with( + request={"parent": _TEST_PARENT, "filter": None} + ) + assert len(my_featurestore_list) == len(_TEST_FEATURESTORE_LIST) + for my_featurestore in my_featurestore_list: + assert type(my_featurestore) == aiplatform.Featurestore + + @pytest.mark.parametrize("sync", [True, False]) + @pytest.mark.usefixtures("get_featurestore_mock") + def test_delete_featurestore(self, delete_featurestore_mock, sync): + aiplatform.init(project=_TEST_PROJECT) + + my_featurestore = aiplatform.Featurestore( + featurestore_name=_TEST_FEATURESTORE_ID + ) + my_featurestore.delete(sync=sync) + + if not sync: + my_featurestore.wait() + + delete_featurestore_mock.assert_called_once_with( + name=my_featurestore.resource_name + ) + + @pytest.mark.usefixtures("get_featurestore_mock") + def test_list_entity_types(self, list_entity_types_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_featurestore = aiplatform.Featurestore( + featurestore_name=_TEST_FEATURESTORE_ID + ) + my_entity_type_list = my_featurestore.list_entity_types() + + list_entity_types_mock.assert_called_once_with( + request={"parent": _TEST_FEATURESTORE_NAME, "filter": None} + ) + assert len(my_entity_type_list) == len(_TEST_ENTITY_TYPE_LIST) + for my_entity_type in my_entity_type_list: + assert type(my_entity_type) == aiplatform.EntityType + + @pytest.mark.parametrize("sync", [True, False]) + @pytest.mark.usefixtures("get_featurestore_mock", "get_entity_type_mock") + def test_delete_entity_types(self, delete_entity_type_mock, sync): + aiplatform.init(project=_TEST_PROJECT) + + my_featurestore = aiplatform.Featurestore( + featurestore_name=_TEST_FEATURESTORE_ID + ) + my_featurestore.delete_entity_types( + entity_type_ids=[_TEST_ENTITY_TYPE_ID, _TEST_ENTITY_TYPE_ID], sync=sync + ) + + if not sync: + my_featurestore.wait() + + delete_entity_type_mock.assert_has_calls( + calls=[ + mock.call(name=_TEST_ENTITY_TYPE_NAME), + mock.call(name=_TEST_ENTITY_TYPE_NAME), + ], + any_order=True, + ) + + +class TestEntityType: + def setup_method(self): + reload(initializer) + reload(aiplatform) + + def teardown_method(self): + initializer.global_pool.shutdown(wait=True) + + @pytest.mark.parametrize( + "entity_type_name, featurestore_id", + [ + (_TEST_ENTITY_TYPE_NAME, None), + (_TEST_ENTITY_TYPE_ID, _TEST_FEATURESTORE_ID), + ], + ) + def test_init_entity_type( + self, entity_type_name, featurestore_id, get_entity_type_mock + ): + aiplatform.init(project=_TEST_PROJECT) + + aiplatform.EntityType( + entity_type_name=entity_type_name, featurestore_id=featurestore_id + ) + + get_entity_type_mock.assert_called_once_with( + name=_TEST_ENTITY_TYPE_NAME, retry=base._DEFAULT_RETRY + ) + + @pytest.mark.usefixtures("get_entity_type_mock") + def test_get_featurestore(self, get_featurestore_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_entity_type = aiplatform.EntityType(entity_type_name=_TEST_ENTITY_TYPE_NAME) + my_featurestore = my_entity_type.get_featurestore() + + get_featurestore_mock.assert_called_once_with( + name=my_featurestore.resource_name, retry=base._DEFAULT_RETRY + ) + assert type(my_featurestore) == aiplatform.Featurestore + + @pytest.mark.usefixtures("get_entity_type_mock") + def test_get_feature(self, get_feature_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_entity_type = aiplatform.EntityType(entity_type_name=_TEST_ENTITY_TYPE_NAME) + my_feature = my_entity_type.get_feature(feature_id=_TEST_FEATURE_ID) + + get_feature_mock.assert_called_once_with( + name=my_feature.resource_name, retry=base._DEFAULT_RETRY + ) + assert type(my_feature) == aiplatform.Feature + + @pytest.mark.usefixtures("get_entity_type_mock") + def test_update_entity_type(self, update_entity_type_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_entity_type = aiplatform.EntityType(entity_type_name=_TEST_ENTITY_TYPE_NAME) + my_entity_type.update(labels=_TEST_LABELS_UPDATE) + + expected_entity_type = gca_entity_type.EntityType( + name=_TEST_ENTITY_TYPE_NAME, labels=_TEST_LABELS_UPDATE, + ) + update_entity_type_mock.assert_called_once_with( + entity_type=expected_entity_type, + update_mask=field_mask_pb2.FieldMask(paths=["labels"]), + metadata=_TEST_REQUEST_METADATA, + ) + + @pytest.mark.parametrize( + "featurestore_name", [_TEST_FEATURESTORE_NAME, _TEST_FEATURESTORE_ID] + ) + def test_list_entity_types(self, featurestore_name, list_entity_types_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_entity_type_list = aiplatform.EntityType.list( + featurestore_name=featurestore_name + ) + + list_entity_types_mock.assert_called_once_with( + request={"parent": _TEST_FEATURESTORE_NAME, "filter": None} + ) + assert len(my_entity_type_list) == len(_TEST_ENTITY_TYPE_LIST) + for my_entity_type in my_entity_type_list: + assert type(my_entity_type) == aiplatform.EntityType + + @pytest.mark.usefixtures("get_entity_type_mock") + def test_list_features(self, list_features_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_entity_type = aiplatform.EntityType(entity_type_name=_TEST_ENTITY_TYPE_NAME) + my_feature_list = my_entity_type.list_features() + + list_features_mock.assert_called_once_with( + request={"parent": _TEST_ENTITY_TYPE_NAME, "filter": None} + ) + assert len(my_feature_list) == len(_TEST_FEATURE_LIST) + for my_feature in my_feature_list: + assert type(my_feature) == aiplatform.Feature + + @pytest.mark.parametrize("sync", [True, False]) + @pytest.mark.usefixtures("get_entity_type_mock", "get_feature_mock") + def test_delete_features(self, delete_feature_mock, sync): + aiplatform.init(project=_TEST_PROJECT) + + my_entity_type = aiplatform.EntityType(entity_type_name=_TEST_ENTITY_TYPE_NAME) + my_entity_type.delete_features( + feature_ids=[_TEST_FEATURE_ID, _TEST_FEATURE_ID], sync=sync + ) + + if not sync: + my_entity_type.wait() + + delete_feature_mock.assert_has_calls( + calls=[ + mock.call(name=_TEST_FEATURE_NAME), + mock.call(name=_TEST_FEATURE_NAME), + ], + any_order=True, + ) + + +class TestFeature: + def setup_method(self): + reload(initializer) + reload(aiplatform) + + def teardown_method(self): + initializer.global_pool.shutdown(wait=True) + + @pytest.mark.parametrize( + "feature_name, entity_type_id, featurestore_id", + [ + (_TEST_FEATURE_NAME, None, None), + (_TEST_FEATURE_ID, _TEST_ENTITY_TYPE_ID, _TEST_FEATURESTORE_ID), + ], + ) + def test_init_feature( + self, feature_name, entity_type_id, featurestore_id, get_feature_mock + ): + aiplatform.init(project=_TEST_PROJECT) + aiplatform.Feature( + feature_name=feature_name, + entity_type_id=entity_type_id, + featurestore_id=featurestore_id, + ) + get_feature_mock.assert_called_once_with( + name=_TEST_FEATURE_NAME, retry=base._DEFAULT_RETRY + ) + + @pytest.mark.usefixtures("get_feature_mock") + def test_get_featurestore(self, get_featurestore_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_feature = aiplatform.Feature(feature_name=_TEST_FEATURE_NAME) + my_featurestore = my_feature.get_featurestore() + + get_featurestore_mock.assert_called_once_with( + name=my_featurestore.resource_name, retry=base._DEFAULT_RETRY + ) + assert type(my_featurestore) == aiplatform.Featurestore + + @pytest.mark.usefixtures("get_feature_mock") + def test_get_entity_type(self, get_entity_type_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_feature = aiplatform.Feature(feature_name=_TEST_FEATURE_NAME) + my_entity_type = my_feature.get_entity_type() + + get_entity_type_mock.assert_called_once_with( + name=my_entity_type.resource_name, retry=base._DEFAULT_RETRY + ) + assert type(my_entity_type) == aiplatform.EntityType + + @pytest.mark.usefixtures("get_feature_mock") + def test_update_feature(self, update_feature_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_feature = aiplatform.Feature(feature_name=_TEST_FEATURE_NAME) + my_feature.update(labels=_TEST_LABELS_UPDATE) + + expected_feature = gca_feature.Feature( + name=_TEST_FEATURE_NAME, labels=_TEST_LABELS_UPDATE, + ) + update_feature_mock.assert_called_once_with( + feature=expected_feature, + update_mask=field_mask_pb2.FieldMask(paths=["labels"]), + metadata=_TEST_REQUEST_METADATA, + ) + + @pytest.mark.parametrize( + "entity_type_name, featurestore_id", + [ + (_TEST_ENTITY_TYPE_NAME, None), + (_TEST_ENTITY_TYPE_ID, _TEST_FEATURESTORE_ID), + ], + ) + def test_list_features(self, entity_type_name, featurestore_id, list_features_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_feature_list = aiplatform.Feature.list( + entity_type_name=entity_type_name, featurestore_id=featurestore_id + ) + + list_features_mock.assert_called_once_with( + request={"parent": _TEST_ENTITY_TYPE_NAME, "filter": None} + ) + assert len(my_feature_list) == len(_TEST_FEATURE_LIST) + for my_feature in my_feature_list: + assert type(my_feature) == aiplatform.Feature + + @pytest.mark.usefixtures("get_feature_mock") + def test_search_features(self, search_features_mock): + aiplatform.init(project=_TEST_PROJECT) + + my_feature_list = aiplatform.Feature.search() + + search_features_mock.assert_called_once_with( + request={"location": _TEST_PARENT, "query": None} + ) + assert len(my_feature_list) == len(_TEST_FEATURE_LIST) + for my_feature in my_feature_list: + assert type(my_feature) == aiplatform.Feature diff --git a/tests/unit/aiplatform/test_helpers.py b/tests/unit/aiplatform/test_helpers.py new file mode 100644 index 0000000000..4d9afe6fa5 --- /dev/null +++ b/tests/unit/aiplatform/test_helpers.py @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- + +# 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. +# + +import importlib +import pytest + +from typing import Sequence + +from google.cloud import aiplatform +from google.cloud.aiplatform import helpers +from google.cloud.aiplatform import initializer + + +class TestContainerUriHelpers: + def setup_method(self): + importlib.reload(initializer) + importlib.reload(aiplatform) + + def teardown_method(self): + initializer.global_pool.shutdown(wait=True) + + def _build_predict_uri_kwargs(self, args: Sequence[str]) -> dict: + """ + Takes list of values for all method parameters and return dict of kwargs, + dropping keywords that were set as None. + """ + func = helpers.get_prebuilt_prediction_container_uri + arg_names = func.__code__.co_varnames[: func.__code__.co_argcount] + return {k: v for k, v in dict(zip(arg_names, args)).items() if v is not None} + + @pytest.mark.parametrize( + "args, expected_uri", + [ + ( + ("tensorflow", "2.6", None, None), + "us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-6:latest", + ), + ( + ("tensorflow", "1.15", "europe-west4", None), + "europe-docker.pkg.dev/vertex-ai/prediction/tf-cpu.1-15:latest", + ), + ( + ("tensorflow", "2.2", None, "gpu"), + "us-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-2:latest", + ), + ( + ("sklearn", "0.24", "asia", "cpu"), + "asia-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-24:latest", + ), + ( + ("sklearn", "0.20", None, None), + "us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-20:latest", + ), + ( + ("xgboost", "1.3", None, None), + "us-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-3:latest", + ), + ( + ("xgboost", "0.90", "europe", None), + "europe-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.0-90:latest", + ), + ], + ) + def test_correct_prediction_uri_args(self, args, expected_uri): + uri = helpers.get_prebuilt_prediction_container_uri( + **self._build_predict_uri_kwargs(args) + ) + + assert uri == expected_uri + + def test_correct_prediction_uri_args_with_init_location(self): + """ + Ensure that aiplatform.init location is used when region + is not provided + """ + uri = aiplatform.helpers.get_prebuilt_prediction_container_uri( + "tensorflow", "2.6" + ) + # SDK default location is us-central1 + assert uri.startswith("us-docker.pkg.dev") + + aiplatform.init(location="asia-northeast3") + uri = aiplatform.helpers.get_prebuilt_prediction_container_uri( + "tensorflow", "2.6" + ) + assert uri.startswith("asia-docker.pkg.dev") + + aiplatform.init(location="europe-west2") + uri = aiplatform.helpers.get_prebuilt_prediction_container_uri( + "xgboost", "0.90" + ) + assert uri.startswith("europe-docker.pkg.dev") + + @pytest.mark.parametrize( + "args, expected_error_msg", + [ + ( + ("pytorch", "1.10", None, None), + "No containers found for framework `pytorch`. Supported frameworks are", + ), + ( + ("tensorflow", "9.15", None, None), + ( + "No serving container for `tensorflow` version `9.15` with accelerator " + "`cpu` found. Supported versions include" + ), + ), + ( + # Make sure region error supercedes version error + ("tensorflow", "9.15", "pluto", None), + "Unsupported container region `pluto`, supported regions are ", + ), + ( + ("tensorflow", "2.2", "narnia", None), + "Unsupported container region `narnia`, supported regions are ", + ), + ( + ("sklearn", "0.24", "asia", "gpu"), + "sklearn containers do not support `gpu` accelerator. Supported accelerators are cpu.", + ), + ( + # Make sure framework error supercedes accelerator error + ("onnx", "1.9", None, "gpu"), + "No containers found for framework `onnx`. Supported frameworks are", + ), + ], + ) + def test_invalid_prediction_uri_args(self, args, expected_error_msg): + + with pytest.raises(ValueError) as err: + helpers.get_prebuilt_prediction_container_uri( + **self._build_predict_uri_kwargs(args) + ) + + assert err.match(expected_error_msg) diff --git a/tests/unit/aiplatform/test_hyperparameter_tuning_job.py b/tests/unit/aiplatform/test_hyperparameter_tuning_job.py index 7b4f434736..c14309ace6 100644 --- a/tests/unit/aiplatform/test_hyperparameter_tuning_job.py +++ b/tests/unit/aiplatform/test_hyperparameter_tuning_job.py @@ -30,14 +30,10 @@ from google.cloud.aiplatform.compat.types import ( encryption_spec as gca_encryption_spec_compat, hyperparameter_tuning_job as gca_hyperparameter_tuning_job_compat, - hyperparameter_tuning_job_v1beta1 as gca_hyperparameter_tuning_job_v1beta1, job_state as gca_job_state_compat, study as gca_study_compat, ) from google.cloud.aiplatform_v1.services.job_service import client as job_service_client -from google.cloud.aiplatform_v1beta1.services.job_service import ( - client as job_service_client_v1beta1, -) import test_custom_job @@ -131,9 +127,7 @@ _TEST_BASE_TRIAL_PROTO = gca_study_compat.Trial() -def _get_hyperparameter_tuning_job_proto( - state=None, name=None, error=None, version="v1" -): +def _get_hyperparameter_tuning_job_proto(state=None, name=None, error=None): hyperparameter_tuning_job_proto = copy.deepcopy( _TEST_BASE_HYPERPARAMETER_TUNING_JOB_PROTO ) @@ -141,18 +135,6 @@ def _get_hyperparameter_tuning_job_proto( hyperparameter_tuning_job_proto.state = state hyperparameter_tuning_job_proto.error = error - if version == "v1beta1": - v1beta1_hyperparameter_tuning_job_proto = ( - gca_hyperparameter_tuning_job_v1beta1.HyperparameterTuningJob() - ) - v1beta1_hyperparameter_tuning_job_proto._pb.MergeFromString( - hyperparameter_tuning_job_proto._pb.SerializeToString() - ) - hyperparameter_tuning_job_proto = v1beta1_hyperparameter_tuning_job_proto - hyperparameter_tuning_job_proto.trial_job_spec.tensorboard = ( - test_custom_job._TEST_TENSORBOARD_NAME - ) - return hyperparameter_tuning_job_proto @@ -166,10 +148,10 @@ def _get_trial_proto(id=None, state=None): def _get_hyperparameter_tuning_job_proto_with_enable_web_access( - state=None, name=None, error=None, version="v1", trials=[] + state=None, name=None, error=None, trials=[] ): hyperparameter_tuning_job_proto = _get_hyperparameter_tuning_job_proto( - state=state, name=name, error=error, version=version + state=state, name=name, error=error, ) hyperparameter_tuning_job_proto.trial_job_spec.enable_web_access = ( test_custom_job._TEST_ENABLE_WEB_ACCESS @@ -342,14 +324,19 @@ def create_hyperparameter_tuning_job_mock_fail(): @pytest.fixture -def create_hyperparameter_tuning_job_v1beta1_mock(): +def create_hyperparameter_tuning_job_mock_with_tensorboard(): with mock.patch.object( - job_service_client_v1beta1.JobServiceClient, "create_hyperparameter_tuning_job" + job_service_client.JobServiceClient, "create_hyperparameter_tuning_job" ) as create_hyperparameter_tuning_job_mock: - create_hyperparameter_tuning_job_mock.return_value = _get_hyperparameter_tuning_job_proto( + hyperparameter_tuning_job_proto = _get_hyperparameter_tuning_job_proto( name=_TEST_HYPERPARAMETERTUNING_JOB_NAME, state=gca_job_state_compat.JobState.JOB_STATE_PENDING, - version="v1beta1", + ) + hyperparameter_tuning_job_proto.trial_job_spec.tensorboard = ( + test_custom_job._TEST_TENSORBOARD_NAME + ) + create_hyperparameter_tuning_job_mock.return_value = ( + hyperparameter_tuning_job_proto ) yield create_hyperparameter_tuning_job_mock @@ -608,7 +595,7 @@ def test_get_hyperparameter_tuning_job(self, get_hyperparameter_tuning_job_mock) @pytest.mark.parametrize("sync", [True, False]) def test_create_hyperparameter_tuning_job_with_tensorboard( self, - create_hyperparameter_tuning_job_v1beta1_mock, + create_hyperparameter_tuning_job_mock_with_tensorboard, get_hyperparameter_tuning_job_mock, sync, ): @@ -659,11 +646,12 @@ def test_create_hyperparameter_tuning_job_with_tensorboard( job.wait() - expected_hyperparameter_tuning_job = _get_hyperparameter_tuning_job_proto( - version="v1beta1" + expected_hyperparameter_tuning_job = _get_hyperparameter_tuning_job_proto() + expected_hyperparameter_tuning_job.trial_job_spec.tensorboard = ( + test_custom_job._TEST_TENSORBOARD_NAME ) - create_hyperparameter_tuning_job_v1beta1_mock.assert_called_once_with( + create_hyperparameter_tuning_job_mock_with_tensorboard.assert_called_once_with( parent=_TEST_PARENT, hyperparameter_tuning_job=expected_hyperparameter_tuning_job, ) diff --git a/tests/unit/aiplatform/test_initializer.py b/tests/unit/aiplatform/test_initializer.py index 7e65c99b4c..f4043a5eba 100644 --- a/tests/unit/aiplatform/test_initializer.py +++ b/tests/unit/aiplatform/test_initializer.py @@ -26,7 +26,7 @@ from google.cloud.aiplatform import initializer from google.cloud.aiplatform.metadata.metadata import metadata_service -from google.cloud.aiplatform import constants +from google.cloud.aiplatform.constants import base as constants from google.cloud.aiplatform import utils from google.cloud.aiplatform_v1.services.model_service import ( diff --git a/tests/unit/aiplatform/test_models.py b/tests/unit/aiplatform/test_models.py index 0c9a649ad8..177cacfb55 100644 --- a/tests/unit/aiplatform/test_models.py +++ b/tests/unit/aiplatform/test_models.py @@ -17,6 +17,7 @@ import importlib from concurrent import futures +import pathlib import pytest from unittest import mock from unittest.mock import patch @@ -423,6 +424,16 @@ def create_client_mock(): yield create_client_mock +@pytest.fixture +def mock_storage_blob_upload_from_filename(): + with patch( + "google.cloud.storage.Blob.upload_from_filename" + ) as mock_blob_upload_from_filename, patch( + "google.cloud.storage.Bucket.exists", return_value=True + ): + yield mock_blob_upload_from_filename + + class TestModel: def setup_method(self): importlib.reload(initializer) @@ -1442,3 +1453,213 @@ def test_get_and_return_subclass_not_found(self): fr"{_TEST_PIPELINE_RESOURCE_NAME}" ) ) + + @pytest.mark.parametrize("sync", [True, False]) + @pytest.mark.parametrize( + "model_file_name", + ["my_model.xgb", "my_model.pkl", "my_model.joblib", "my_model.bst"], + ) + def test_upload_xgboost_model_file_uploads_and_gets_model( + self, + tmp_path: pathlib.Path, + model_file_name: str, + mock_storage_blob_upload_from_filename, + upload_model_mock, + get_model_mock, + sync: bool, + ): + model_file_path = tmp_path / model_file_name + model_file_path.touch() + + my_model = models.Model.upload_xgboost_model_file( + model_file_path=str(model_file_path), + xgboost_version="1.4", + display_name=_TEST_MODEL_NAME, + project=_TEST_PROJECT, + location=_TEST_LOCATION, + sync=sync, + ) + + if not sync: + my_model.wait() + + upload_model_mock.assert_called_once() + upload_model_call_kwargs = upload_model_mock.call_args[1] + upload_model_model = upload_model_call_kwargs["model"] + + # Verifying the container image selection + assert ( + upload_model_model.container_spec.image_uri + == "us-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-4:latest" + ) + + # Verifying the staging bucket name generation + assert upload_model_model.artifact_uri.startswith( + f"gs://{_TEST_PROJECT}-vertex-staging-{_TEST_LOCATION}" + ) + assert "/vertex_ai_auto_staging/" in upload_model_model.artifact_uri + + # Verifying that the model was renamed to a file name that is acceptable for Model.upload + staged_model_file_path = mock_storage_blob_upload_from_filename.call_args[1][ + "filename" + ] + staged_model_file_name = staged_model_file_path.split("/")[-1] + assert staged_model_file_name in ["model.bst", "model.pkl", "model.joblib"] + + @pytest.mark.parametrize("sync", [True, False]) + @pytest.mark.parametrize( + "model_file_name", + [ + "model.bst", + "model.pkl", + "model.joblib", + "saved_model.pb", + "saved_model.pbtxt", + ], + ) + def test_upload_stages_data_uploads_and_gets_model( + self, + tmp_path: pathlib.Path, + model_file_name: str, + mock_storage_blob_upload_from_filename, + upload_model_mock, + get_model_mock, + sync: bool, + ): + model_file_path = tmp_path / model_file_name + model_file_path.touch() + + my_model = models.Model.upload( + artifact_uri=str(tmp_path), + serving_container_image_uri="us-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-4:latest", + display_name=_TEST_MODEL_NAME, + project=_TEST_PROJECT, + location=_TEST_LOCATION, + sync=sync, + ) + + if not sync: + my_model.wait() + + upload_model_mock.assert_called_once() + upload_model_call_kwargs = upload_model_mock.call_args[1] + upload_model_model = upload_model_call_kwargs["model"] + + # Verifying the staging bucket name generation + assert upload_model_model.artifact_uri.startswith( + f"gs://{_TEST_PROJECT}-vertex-staging-{_TEST_LOCATION}" + ) + assert "/vertex_ai_auto_staging/" in upload_model_model.artifact_uri + + # Verifying that the model was renamed to a file name that is acceptable for Model.upload + staged_model_file_path = mock_storage_blob_upload_from_filename.call_args[1][ + "filename" + ] + staged_model_file_name = staged_model_file_path.split("/")[-1] + assert staged_model_file_name in [ + "model.bst", + "model.pkl", + "model.joblib", + "saved_model.pb", + "saved_model.pbtxt", + ] + + @pytest.mark.parametrize("sync", [True, False]) + @pytest.mark.parametrize( + "model_file_name", ["my_model.pkl", "my_model.joblib"], + ) + def test_upload_scikit_learn_model_file_uploads_and_gets_model( + self, + tmp_path: pathlib.Path, + model_file_name: str, + mock_storage_blob_upload_from_filename, + upload_model_mock, + get_model_mock, + sync: bool, + ): + model_file_path = tmp_path / model_file_name + model_file_path.touch() + + my_model = models.Model.upload_scikit_learn_model_file( + model_file_path=str(model_file_path), + sklearn_version="0.24", + display_name=_TEST_MODEL_NAME, + project=_TEST_PROJECT, + location=_TEST_LOCATION, + sync=sync, + ) + + if not sync: + my_model.wait() + + upload_model_mock.assert_called_once() + upload_model_call_kwargs = upload_model_mock.call_args[1] + upload_model_model = upload_model_call_kwargs["model"] + + # Verifying the container image selection + assert ( + upload_model_model.container_spec.image_uri + == "us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-24:latest" + ) + + # Verifying the staging bucket name generation + assert upload_model_model.artifact_uri.startswith( + f"gs://{_TEST_PROJECT}-vertex-staging-{_TEST_LOCATION}" + ) + assert "/vertex_ai_auto_staging/" in upload_model_model.artifact_uri + + # Verifying that the model was renamed to a file name that is acceptable for Model.upload + staged_model_file_path = mock_storage_blob_upload_from_filename.call_args[1][ + "filename" + ] + staged_model_file_name = staged_model_file_path.split("/")[-1] + assert staged_model_file_name in ["model.pkl", "model.joblib"] + + @pytest.mark.parametrize("sync", [True, False]) + def test_upload_tensorflow_saved_model_uploads_and_gets_model( + self, + tmp_path: pathlib.Path, + mock_storage_blob_upload_from_filename, + upload_model_mock, + get_model_mock, + sync: bool, + ): + saved_model_dir = tmp_path / "saved_model" + saved_model_dir.mkdir() + (saved_model_dir / "saved_model.pb").touch() + + my_model = models.Model.upload_tensorflow_saved_model( + saved_model_dir=str(saved_model_dir), + tensorflow_version="2.6", + use_gpu=True, + display_name=_TEST_MODEL_NAME, + project=_TEST_PROJECT, + location=_TEST_LOCATION, + sync=sync, + ) + + if not sync: + my_model.wait() + + upload_model_mock.assert_called_once() + upload_model_call_kwargs = upload_model_mock.call_args[1] + upload_model_model = upload_model_call_kwargs["model"] + + # Verifying the container image selection + assert ( + upload_model_model.container_spec.image_uri + == "us-docker.pkg.dev/vertex-ai/prediction/tf2-gpu.2-6:latest" + ) + + # Verifying the staging bucket name generation + assert upload_model_model.artifact_uri.startswith( + f"gs://{_TEST_PROJECT}-vertex-staging-{_TEST_LOCATION}" + ) + assert "/vertex_ai_auto_staging/" in upload_model_model.artifact_uri + + # Verifying that the model files were uploaded + staged_model_file_path = mock_storage_blob_upload_from_filename.call_args[1][ + "filename" + ] + staged_model_file_name = staged_model_file_path.split("/")[-1] + assert staged_model_file_name in ["saved_model.pb", "saved_model.pbtxt"] diff --git a/tests/unit/aiplatform/test_tensorboard.py b/tests/unit/aiplatform/test_tensorboard.py index ffa4c72850..38ea935950 100644 --- a/tests/unit/aiplatform/test_tensorboard.py +++ b/tests/unit/aiplatform/test_tensorboard.py @@ -32,11 +32,11 @@ from google.cloud.aiplatform import initializer from google.cloud.aiplatform import tensorboard -from google.cloud.aiplatform_v1beta1.services.tensorboard_service import ( +from google.cloud.aiplatform_v1.services.tensorboard_service import ( client as tensorboard_service_client, ) -from google.cloud.aiplatform_v1beta1.types import ( +from google.cloud.aiplatform_v1.types import ( tensorboard as gca_tensorboard, tensorboard_service as gca_tensorboard_service, encryption_spec as gca_encryption_spec, diff --git a/tests/unit/aiplatform/test_training_utils.py b/tests/unit/aiplatform/test_training_utils.py index 626d5c1d2a..99d49b7ead 100644 --- a/tests/unit/aiplatform/test_training_utils.py +++ b/tests/unit/aiplatform/test_training_utils.py @@ -60,6 +60,7 @@ "projects/myproj/locations/us-central1/tensorboards/1234" ) _TEST_CLOUD_ML_JOB_ID = "myjob" +_TEST_AIP_HTTP_HANDLER_PORT = "5678" class TestTrainingUtils: @@ -73,6 +74,7 @@ def mock_environment(self): "AIP_CHECKPOINT_DIR": _TEST_CHECKPOINT_DIR, "AIP_TENSORBOARD_LOG_DIR": _TEST_TENSORBOARD_LOG_DIR, "AIP_TF_PROFILER_PORT": _TEST_AIP_TF_PROFILER_PORT, + "AIP_HTTP_HANDLER_PORT": _TEST_AIP_HTTP_HANDLER_PORT, "AIP_TENSORBOARD_API_URI": _TEST_TENSORBOARD_API_URI, "AIP_TENSORBOARD_RESOURCE_NAME": _TEST_TENSORBOARD_RESOURCE_NAME, "CLOUD_ML_JOB_ID": _TEST_CLOUD_ML_JOB_ID, @@ -192,3 +194,12 @@ def test_cloud_ml_job_id(self): def test_cloud_ml_job_id_none(self): reload(environment_variables) assert environment_variables.cloud_ml_job_id is None + + @pytest.mark.usefixtures("mock_environment") + def test_http_handler_port(self): + reload(environment_variables) + assert environment_variables.http_handler_port == _TEST_AIP_HTTP_HANDLER_PORT + + def test_http_handler_port_none(self): + reload(environment_variables) + assert environment_variables.http_handler_port is None diff --git a/tests/unit/aiplatform/test_uploader.py b/tests/unit/aiplatform/test_uploader.py index fd071d0e2b..b0d41e475e 100644 --- a/tests/unit/aiplatform/test_uploader.py +++ b/tests/unit/aiplatform/test_uploader.py @@ -46,22 +46,20 @@ from google.cloud.aiplatform.tensorboard.plugins.tf_profiler import profile_uploader import google.cloud.aiplatform.tensorboard.uploader as uploader_lib from google.cloud import storage -from google.cloud.aiplatform.compat.services import tensorboard_service_client_v1beta1 -from google.cloud.aiplatform_v1beta1.services.tensorboard_service.transports import ( - grpc as transports_grpc, -) -from google.cloud.aiplatform.compat.types import ( - tensorboard_data_v1beta1 as tensorboard_data, - tensorboard_service_v1beta1 as tensorboard_service, +from google.cloud.aiplatform_v1.services.tensorboard_service import ( + client as tensorboard_service_client, ) -from google.cloud.aiplatform.compat.types import ( - tensorboard_experiment_v1beta1 as tensorboard_experiment_type, +from google.cloud.aiplatform_v1.services.tensorboard_service.transports import ( + grpc as transports_grpc, ) -from google.cloud.aiplatform.compat.types import ( - tensorboard_run_v1beta1 as tensorboard_run_type, +from google.cloud.aiplatform_v1.types import tensorboard_data +from google.cloud.aiplatform_v1.types import tensorboard_service +from google.cloud.aiplatform_v1.types import ( + tensorboard_experiment as tensorboard_experiment_type, ) -from google.cloud.aiplatform.compat.types import ( - tensorboard_time_series_v1beta1 as tensorboard_time_series_type, +from google.cloud.aiplatform_v1.types import tensorboard_run as tensorboard_run_type +from google.cloud.aiplatform_v1.types import ( + tensorboard_time_series as tensorboard_time_series_type, ) from google.protobuf import timestamp_pb2 from google.protobuf import message @@ -160,7 +158,7 @@ def create_tensorboard_time_series( service_descriptors=[], time=grpc_testing.strict_real_time() ) mock_client = mock.Mock( - spec=tensorboard_service_client_v1beta1.TensorboardServiceClient( + spec=tensorboard_service_client.TensorboardServiceClient( transport=transports_grpc.TensorboardServiceGrpcTransport( channel=test_channel ) diff --git a/tests/unit/aiplatform/test_uploader_main.py b/tests/unit/aiplatform/test_uploader_main.py new file mode 100644 index 0000000000..79c86b22fc --- /dev/null +++ b/tests/unit/aiplatform/test_uploader_main.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# 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. +# + +import pytest + +from importlib import reload +from unittest.mock import patch + +from google.api_core import exceptions +from google.cloud import aiplatform +from google.cloud.aiplatform import initializer +from google.cloud.aiplatform.tensorboard import uploader_main +from google.cloud.aiplatform.compat.types import job_state as gca_job_state_compat +from google.cloud.aiplatform.compat.types import custom_job as gca_custom_job_compat +from google.cloud.aiplatform_v1.services.job_service import client as job_service_client + +_TEST_PROJECT = "test-project" +_TEST_LOCATION = "us-central1" +_TEST_PARENT = f"projects/{_TEST_PROJECT}/locations/{_TEST_LOCATION}" +_TEST_CUSTOM_JOB_ID = "445768" +_TEST_CUSTOM_JOB_NAME = f"{_TEST_PARENT}/customJobs/{_TEST_CUSTOM_JOB_ID}" +_TEST_CUSTOM_JOBS_DISPLAY_NAME = "a custom job display name" +_TEST_PASSED_IN_EXPERIMENT_DISPLAY_NAME = "someDisplayName" + + +def _get_custom_job_proto(state=None, name=None): + custom_job_proto = gca_custom_job_compat.CustomJob() + custom_job_proto.name = name + custom_job_proto.state = state + custom_job_proto.display_name = _TEST_CUSTOM_JOBS_DISPLAY_NAME + return custom_job_proto + + +@pytest.fixture +def get_custom_job_mock_not_found(): + with patch.object( + job_service_client.JobServiceClient, "get_custom_job" + ) as get_custom_job_mock: + get_custom_job_mock.side_effect = exceptions.NotFound("not found") + yield get_custom_job_mock + + +@pytest.fixture +def get_custom_job_mock(): + with patch.object( + job_service_client.JobServiceClient, "get_custom_job" + ) as get_custom_job_mock: + get_custom_job_mock.side_effect = [ + _get_custom_job_proto( + name=_TEST_CUSTOM_JOB_NAME, + state=gca_job_state_compat.JobState.JOB_STATE_SUCCEEDED, + ), + ] + yield get_custom_job_mock + + +class TestUploaderMain: + def setup_method(self): + reload(initializer) + reload(aiplatform) + aiplatform.init(project=_TEST_PROJECT, location=_TEST_LOCATION) + + def teardown_method(self): + initializer.global_pool.shutdown(wait=True) + + def test_get_default_custom_job_display_name(self, get_custom_job_mock): + aiplatform.init(project=_TEST_PROJECT) + assert ( + uploader_main.get_experiment_display_name_with_override( + _TEST_CUSTOM_JOB_ID, None, _TEST_PROJECT, _TEST_LOCATION + ) + == _TEST_CUSTOM_JOBS_DISPLAY_NAME + ) + + def test_non_decimal_experiment_name(self, get_custom_job_mock): + aiplatform.init(project=_TEST_PROJECT) + assert ( + uploader_main.get_experiment_display_name_with_override( + "someExperimentName", + _TEST_PASSED_IN_EXPERIMENT_DISPLAY_NAME, + _TEST_PROJECT, + _TEST_LOCATION, + ) + == _TEST_PASSED_IN_EXPERIMENT_DISPLAY_NAME + ) + get_custom_job_mock.assert_not_called() + + def test_display_name_already_specified(self, get_custom_job_mock): + aiplatform.init(project=_TEST_PROJECT) + assert ( + uploader_main.get_experiment_display_name_with_override( + _TEST_CUSTOM_JOB_ID, + _TEST_PASSED_IN_EXPERIMENT_DISPLAY_NAME, + _TEST_PROJECT, + _TEST_LOCATION, + ) + == _TEST_PASSED_IN_EXPERIMENT_DISPLAY_NAME + ) + get_custom_job_mock.assert_not_called() + + def test_custom_job_not_found(self, get_custom_job_mock_not_found): + aiplatform.init(project=_TEST_PROJECT) + assert ( + uploader_main.get_experiment_display_name_with_override( + _TEST_CUSTOM_JOB_ID, + _TEST_PASSED_IN_EXPERIMENT_DISPLAY_NAME, + _TEST_PROJECT, + _TEST_LOCATION, + ) + == _TEST_PASSED_IN_EXPERIMENT_DISPLAY_NAME + ) diff --git a/tests/unit/enhanced_library/test_value_converter.py b/tests/unit/enhanced_library/test_value_converter.py index 4cbaeed7cf..4bb24372e2 100644 --- a/tests/unit/enhanced_library/test_value_converter.py +++ b/tests/unit/enhanced_library/test_value_converter.py @@ -13,7 +13,7 @@ # limitations under the License. from __future__ import absolute_import -from google.cloud.aiplatform.helpers import value_converter +from google.cloud.aiplatform.utils.enhanced_library import value_converter from google.protobuf import json_format from google.protobuf.struct_pb2 import Value import proto diff --git a/tests/unit/gapic/aiplatform_v1/test_dataset_service.py b/tests/unit/gapic/aiplatform_v1/test_dataset_service.py index 5d1554bc7d..f329e5dd81 100644 --- a/tests/unit/gapic/aiplatform_v1/test_dataset_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_dataset_service.py @@ -643,8 +643,12 @@ def test_create_dataset_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].dataset == gca_dataset.Dataset(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].dataset + mock_val = gca_dataset.Dataset(name="name_value") + assert arg == mock_val def test_create_dataset_flattened_error(): @@ -684,8 +688,12 @@ async def test_create_dataset_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].dataset == gca_dataset.Dataset(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].dataset + mock_val = gca_dataset.Dataset(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -871,7 +879,9 @@ def test_get_dataset_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_dataset_flattened_error(): @@ -905,7 +915,9 @@ async def test_get_dataset_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1096,8 +1108,12 @@ def test_update_dataset_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].dataset == gca_dataset.Dataset(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].dataset + mock_val = gca_dataset.Dataset(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_dataset_flattened_error(): @@ -1136,8 +1152,12 @@ async def test_update_dataset_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].dataset == gca_dataset.Dataset(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].dataset + mock_val = gca_dataset.Dataset(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 @@ -1309,7 +1329,9 @@ def test_list_datasets_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_datasets_flattened_error(): @@ -1345,7 +1367,9 @@ async def test_list_datasets_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1631,7 +1655,9 @@ def test_delete_dataset_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_dataset_flattened_error(): @@ -1667,7 +1693,9 @@ async def test_delete_dataset_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1836,10 +1864,14 @@ def test_import_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].import_configs == [ + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].import_configs + mock_val = [ dataset.ImportDataConfig(gcs_source=io.GcsSource(uris=["uris_value"])) ] + assert arg == mock_val def test_import_data_flattened_error(): @@ -1884,10 +1916,14 @@ async def test_import_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].import_configs == [ + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].import_configs + mock_val = [ dataset.ImportDataConfig(gcs_source=io.GcsSource(uris=["uris_value"])) ] + assert arg == mock_val @pytest.mark.asyncio @@ -2062,12 +2098,16 @@ def test_export_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].export_config == dataset.ExportDataConfig( + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].export_config + mock_val = dataset.ExportDataConfig( gcs_destination=io.GcsDestination( output_uri_prefix="output_uri_prefix_value" ) ) + assert arg == mock_val def test_export_data_flattened_error(): @@ -2116,12 +2156,16 @@ async def test_export_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].export_config == dataset.ExportDataConfig( + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].export_config + mock_val = dataset.ExportDataConfig( gcs_destination=io.GcsDestination( output_uri_prefix="output_uri_prefix_value" ) ) + assert arg == mock_val @pytest.mark.asyncio @@ -2297,7 +2341,9 @@ def test_list_data_items_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_data_items_flattened_error(): @@ -2333,7 +2379,9 @@ async def test_list_data_items_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2666,7 +2714,9 @@ def test_get_annotation_spec_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_annotation_spec_flattened_error(): @@ -2704,7 +2754,9 @@ async def test_get_annotation_spec_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2874,7 +2926,9 @@ def test_list_annotations_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_annotations_flattened_error(): @@ -2910,7 +2964,9 @@ async def test_list_annotations_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_endpoint_service.py b/tests/unit/gapic/aiplatform_v1/test_endpoint_service.py index 63647cdeb5..3b92c2af95 100644 --- a/tests/unit/gapic/aiplatform_v1/test_endpoint_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_endpoint_service.py @@ -646,15 +646,24 @@ def test_create_endpoint_flattened(): # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.create_endpoint( - parent="parent_value", endpoint=gca_endpoint.Endpoint(name="name_value"), + parent="parent_value", + endpoint=gca_endpoint.Endpoint(name="name_value"), + endpoint_id="endpoint_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] - assert args[0].parent == "parent_value" - assert args[0].endpoint == gca_endpoint.Endpoint(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].endpoint + mock_val = gca_endpoint.Endpoint(name="name_value") + assert arg == mock_val + arg = args[0].endpoint_id + mock_val = "endpoint_id_value" + assert arg == mock_val def test_create_endpoint_flattened_error(): @@ -667,6 +676,7 @@ def test_create_endpoint_flattened_error(): endpoint_service.CreateEndpointRequest(), parent="parent_value", endpoint=gca_endpoint.Endpoint(name="name_value"), + endpoint_id="endpoint_id_value", ) @@ -687,15 +697,24 @@ async def test_create_endpoint_flattened_async(): # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. response = await client.create_endpoint( - parent="parent_value", endpoint=gca_endpoint.Endpoint(name="name_value"), + parent="parent_value", + endpoint=gca_endpoint.Endpoint(name="name_value"), + endpoint_id="endpoint_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] - assert args[0].parent == "parent_value" - assert args[0].endpoint == gca_endpoint.Endpoint(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].endpoint + mock_val = gca_endpoint.Endpoint(name="name_value") + assert arg == mock_val + arg = args[0].endpoint_id + mock_val = "endpoint_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -711,6 +730,7 @@ async def test_create_endpoint_flattened_error_async(): endpoint_service.CreateEndpointRequest(), parent="parent_value", endpoint=gca_endpoint.Endpoint(name="name_value"), + endpoint_id="endpoint_id_value", ) @@ -734,6 +754,7 @@ def test_get_endpoint( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, model_deployment_monitoring_job="model_deployment_monitoring_job_value", ) response = client.get_endpoint(request) @@ -750,6 +771,7 @@ def test_get_endpoint( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True assert ( response.model_deployment_monitoring_job == "model_deployment_monitoring_job_value" @@ -797,6 +819,7 @@ async def test_get_endpoint_async( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, model_deployment_monitoring_job="model_deployment_monitoring_job_value", ) ) @@ -814,6 +837,7 @@ async def test_get_endpoint_async( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True assert ( response.model_deployment_monitoring_job == "model_deployment_monitoring_job_value" @@ -891,7 +915,9 @@ def test_get_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_endpoint_flattened_error(): @@ -925,7 +951,9 @@ async def test_get_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1095,7 +1123,9 @@ def test_list_endpoints_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_endpoints_flattened_error(): @@ -1131,7 +1161,9 @@ async def test_list_endpoints_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1318,6 +1350,7 @@ def test_update_endpoint( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, model_deployment_monitoring_job="model_deployment_monitoring_job_value", ) response = client.update_endpoint(request) @@ -1334,6 +1367,7 @@ def test_update_endpoint( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True assert ( response.model_deployment_monitoring_job == "model_deployment_monitoring_job_value" @@ -1381,6 +1415,7 @@ async def test_update_endpoint_async( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, model_deployment_monitoring_job="model_deployment_monitoring_job_value", ) ) @@ -1398,6 +1433,7 @@ async def test_update_endpoint_async( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True assert ( response.model_deployment_monitoring_job == "model_deployment_monitoring_job_value" @@ -1484,8 +1520,12 @@ def test_update_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].endpoint == gca_endpoint.Endpoint(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].endpoint + mock_val = gca_endpoint.Endpoint(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_endpoint_flattened_error(): @@ -1526,8 +1566,12 @@ async def test_update_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].endpoint == gca_endpoint.Endpoint(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].endpoint + mock_val = gca_endpoint.Endpoint(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 @@ -1693,7 +1737,9 @@ def test_delete_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_endpoint_flattened_error(): @@ -1729,7 +1775,9 @@ async def test_delete_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1903,15 +1951,21 @@ def test_deploy_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].deployed_model == gca_endpoint.DeployedModel( + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].deployed_model + mock_val = gca_endpoint.DeployedModel( dedicated_resources=machine_resources.DedicatedResources( machine_spec=machine_resources.MachineSpec( machine_type="machine_type_value" ) ) ) - assert args[0].traffic_split == {"key_value": 541} + assert arg == mock_val + arg = args[0].traffic_split + mock_val = {"key_value": 541} + assert arg == mock_val def test_deploy_model_flattened_error(): @@ -1966,15 +2020,21 @@ async def test_deploy_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].deployed_model == gca_endpoint.DeployedModel( + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].deployed_model + mock_val = gca_endpoint.DeployedModel( dedicated_resources=machine_resources.DedicatedResources( machine_spec=machine_resources.MachineSpec( machine_type="machine_type_value" ) ) ) - assert args[0].traffic_split == {"key_value": 541} + assert arg == mock_val + arg = args[0].traffic_split + mock_val = {"key_value": 541} + assert arg == mock_val @pytest.mark.asyncio @@ -2151,9 +2211,15 @@ def test_undeploy_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].deployed_model_id == "deployed_model_id_value" - assert args[0].traffic_split == {"key_value": 541} + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].deployed_model_id + mock_val = "deployed_model_id_value" + assert arg == mock_val + arg = args[0].traffic_split + mock_val = {"key_value": 541} + assert arg == mock_val def test_undeploy_model_flattened_error(): @@ -2196,9 +2262,15 @@ async def test_undeploy_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].deployed_model_id == "deployed_model_id_value" - assert args[0].traffic_split == {"key_value": 541} + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].deployed_model_id + mock_val = "deployed_model_id_value" + assert arg == mock_val + arg = args[0].traffic_split + mock_val = {"key_value": 541} + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_featurestore_online_serving_service.py b/tests/unit/gapic/aiplatform_v1/test_featurestore_online_serving_service.py index b1f3730641..2a5deb4265 100644 --- a/tests/unit/gapic/aiplatform_v1/test_featurestore_online_serving_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_featurestore_online_serving_service.py @@ -698,7 +698,9 @@ def test_read_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val def test_read_feature_values_flattened_error(): @@ -739,7 +741,9 @@ async def test_read_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val @pytest.mark.asyncio @@ -940,7 +944,9 @@ def test_streaming_read_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val def test_streaming_read_feature_values_flattened_error(): @@ -983,7 +989,9 @@ async def test_streaming_read_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_featurestore_service.py b/tests/unit/gapic/aiplatform_v1/test_featurestore_service.py index 2bb2805cce..90402f0bcd 100644 --- a/tests/unit/gapic/aiplatform_v1/test_featurestore_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_featurestore_service.py @@ -681,14 +681,22 @@ def test_create_featurestore_flattened(): client.create_featurestore( parent="parent_value", featurestore=gca_featurestore.Featurestore(name="name_value"), + featurestore_id="featurestore_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] - assert args[0].parent == "parent_value" - assert args[0].featurestore == gca_featurestore.Featurestore(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].featurestore + mock_val = gca_featurestore.Featurestore(name="name_value") + assert arg == mock_val + arg = args[0].featurestore_id + mock_val = "featurestore_id_value" + assert arg == mock_val def test_create_featurestore_flattened_error(): @@ -703,6 +711,7 @@ def test_create_featurestore_flattened_error(): featurestore_service.CreateFeaturestoreRequest(), parent="parent_value", featurestore=gca_featurestore.Featurestore(name="name_value"), + featurestore_id="featurestore_id_value", ) @@ -727,14 +736,22 @@ async def test_create_featurestore_flattened_async(): response = await client.create_featurestore( parent="parent_value", featurestore=gca_featurestore.Featurestore(name="name_value"), + featurestore_id="featurestore_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] - assert args[0].parent == "parent_value" - assert args[0].featurestore == gca_featurestore.Featurestore(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].featurestore + mock_val = gca_featurestore.Featurestore(name="name_value") + assert arg == mock_val + arg = args[0].featurestore_id + mock_val = "featurestore_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -750,6 +767,7 @@ async def test_create_featurestore_flattened_error_async(): featurestore_service.CreateFeaturestoreRequest(), parent="parent_value", featurestore=gca_featurestore.Featurestore(name="name_value"), + featurestore_id="featurestore_id_value", ) @@ -919,7 +937,9 @@ def test_get_featurestore_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_featurestore_flattened_error(): @@ -957,7 +977,9 @@ async def test_get_featurestore_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1144,7 +1166,9 @@ def test_list_featurestores_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_featurestores_flattened_error(): @@ -1184,7 +1208,9 @@ async def test_list_featurestores_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1544,8 +1570,12 @@ def test_update_featurestore_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].featurestore == gca_featurestore.Featurestore(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].featurestore + mock_val = gca_featurestore.Featurestore(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_featurestore_flattened_error(): @@ -1590,8 +1620,12 @@ async def test_update_featurestore_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].featurestore == gca_featurestore.Featurestore(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].featurestore + mock_val = gca_featurestore.Featurestore(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 @@ -1776,8 +1810,12 @@ def test_delete_featurestore_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].force == True + 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_featurestore_flattened_error(): @@ -1819,8 +1857,12 @@ async def test_delete_featurestore_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].force == True + 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 @@ -2000,14 +2042,22 @@ def test_create_entity_type_flattened(): client.create_entity_type( parent="parent_value", entity_type=gca_entity_type.EntityType(name="name_value"), + entity_type_id="entity_type_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] - assert args[0].parent == "parent_value" - assert args[0].entity_type == gca_entity_type.EntityType(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].entity_type + mock_val = gca_entity_type.EntityType(name="name_value") + assert arg == mock_val + arg = args[0].entity_type_id + mock_val = "entity_type_id_value" + assert arg == mock_val def test_create_entity_type_flattened_error(): @@ -2022,6 +2072,7 @@ def test_create_entity_type_flattened_error(): featurestore_service.CreateEntityTypeRequest(), parent="parent_value", entity_type=gca_entity_type.EntityType(name="name_value"), + entity_type_id="entity_type_id_value", ) @@ -2046,14 +2097,22 @@ async def test_create_entity_type_flattened_async(): response = await client.create_entity_type( parent="parent_value", entity_type=gca_entity_type.EntityType(name="name_value"), + entity_type_id="entity_type_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] - assert args[0].parent == "parent_value" - assert args[0].entity_type == gca_entity_type.EntityType(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].entity_type + mock_val = gca_entity_type.EntityType(name="name_value") + assert arg == mock_val + arg = args[0].entity_type_id + mock_val = "entity_type_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2069,6 +2128,7 @@ async def test_create_entity_type_flattened_error_async(): featurestore_service.CreateEntityTypeRequest(), parent="parent_value", entity_type=gca_entity_type.EntityType(name="name_value"), + entity_type_id="entity_type_id_value", ) @@ -2234,7 +2294,9 @@ def test_get_entity_type_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_entity_type_flattened_error(): @@ -2272,7 +2334,9 @@ async def test_get_entity_type_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2459,7 +2523,9 @@ def test_list_entity_types_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_entity_types_flattened_error(): @@ -2499,7 +2565,9 @@ async def test_list_entity_types_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2855,8 +2923,12 @@ def test_update_entity_type_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == gca_entity_type.EntityType(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].entity_type + mock_val = gca_entity_type.EntityType(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_entity_type_flattened_error(): @@ -2901,8 +2973,12 @@ async def test_update_entity_type_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == gca_entity_type.EntityType(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].entity_type + mock_val = gca_entity_type.EntityType(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 @@ -3087,8 +3163,12 @@ def test_delete_entity_type_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].force == True + 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_entity_type_flattened_error(): @@ -3130,8 +3210,12 @@ async def test_delete_entity_type_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].force == True + 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 @@ -3297,15 +3381,24 @@ def test_create_feature_flattened(): # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.create_feature( - parent="parent_value", feature=gca_feature.Feature(name="name_value"), + parent="parent_value", + feature=gca_feature.Feature(name="name_value"), + feature_id="feature_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] - assert args[0].parent == "parent_value" - assert args[0].feature == gca_feature.Feature(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].feature + mock_val = gca_feature.Feature(name="name_value") + assert arg == mock_val + arg = args[0].feature_id + mock_val = "feature_id_value" + assert arg == mock_val def test_create_feature_flattened_error(): @@ -3320,6 +3413,7 @@ def test_create_feature_flattened_error(): featurestore_service.CreateFeatureRequest(), parent="parent_value", feature=gca_feature.Feature(name="name_value"), + feature_id="feature_id_value", ) @@ -3340,15 +3434,24 @@ async def test_create_feature_flattened_async(): # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. response = await client.create_feature( - parent="parent_value", feature=gca_feature.Feature(name="name_value"), + parent="parent_value", + feature=gca_feature.Feature(name="name_value"), + feature_id="feature_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] - assert args[0].parent == "parent_value" - assert args[0].feature == gca_feature.Feature(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].feature + mock_val = gca_feature.Feature(name="name_value") + assert arg == mock_val + arg = args[0].feature_id + mock_val = "feature_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3364,6 +3467,7 @@ async def test_create_feature_flattened_error_async(): featurestore_service.CreateFeatureRequest(), parent="parent_value", feature=gca_feature.Feature(name="name_value"), + feature_id="feature_id_value", ) @@ -3535,10 +3639,12 @@ def test_batch_create_features_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].requests == [ - featurestore_service.CreateFeatureRequest(parent="parent_value") - ] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [featurestore_service.CreateFeatureRequest(parent="parent_value")] + assert arg == mock_val def test_batch_create_features_flattened_error(): @@ -3583,10 +3689,12 @@ async def test_batch_create_features_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].requests == [ - featurestore_service.CreateFeatureRequest(parent="parent_value") - ] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [featurestore_service.CreateFeatureRequest(parent="parent_value")] + assert arg == mock_val @pytest.mark.asyncio @@ -3772,7 +3880,9 @@ def test_get_feature_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_feature_flattened_error(): @@ -3808,7 +3918,9 @@ async def test_get_feature_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3983,7 +4095,9 @@ def test_list_features_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_features_flattened_error(): @@ -4021,7 +4135,9 @@ async def test_list_features_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4347,8 +4463,12 @@ def test_update_feature_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].feature == gca_feature.Feature(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].feature + mock_val = gca_feature.Feature(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_feature_flattened_error(): @@ -4389,8 +4509,12 @@ async def test_update_feature_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].feature == gca_feature.Feature(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].feature + mock_val = gca_feature.Feature(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 @@ -4561,7 +4685,9 @@ def test_delete_feature_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_feature_flattened_error(): @@ -4599,7 +4725,9 @@ async def test_delete_feature_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4781,7 +4909,9 @@ def test_import_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val def test_import_feature_values_flattened_error(): @@ -4822,7 +4952,9 @@ async def test_import_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5009,7 +5141,9 @@ def test_batch_read_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].featurestore == "featurestore_value" + arg = args[0].featurestore + mock_val = "featurestore_value" + assert arg == mock_val def test_batch_read_feature_values_flattened_error(): @@ -5052,7 +5186,9 @@ async def test_batch_read_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].featurestore == "featurestore_value" + arg = args[0].featurestore + mock_val = "featurestore_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5235,7 +5371,9 @@ def test_export_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val def test_export_feature_values_flattened_error(): @@ -5276,7 +5414,9 @@ async def test_export_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5454,8 +5594,12 @@ def test_search_features_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].location == "location_value" - assert args[0].query == "query_value" + arg = args[0].location + mock_val = "location_value" + assert arg == mock_val + arg = args[0].query + mock_val = "query_value" + assert arg == mock_val def test_search_features_flattened_error(): @@ -5497,8 +5641,12 @@ async def test_search_features_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].location == "location_value" - assert args[0].query == "query_value" + arg = args[0].location + mock_val = "location_value" + assert arg == mock_val + arg = args[0].query + mock_val = "query_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_index_endpoint_service.py b/tests/unit/gapic/aiplatform_v1/test_index_endpoint_service.py index d777d6d3d0..2917a37ed9 100644 --- a/tests/unit/gapic/aiplatform_v1/test_index_endpoint_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_index_endpoint_service.py @@ -682,10 +682,12 @@ def test_create_index_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].index_endpoint == gca_index_endpoint.IndexEndpoint( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].index_endpoint + mock_val = gca_index_endpoint.IndexEndpoint(name="name_value") + assert arg == mock_val def test_create_index_endpoint_flattened_error(): @@ -730,10 +732,12 @@ async def test_create_index_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].index_endpoint == gca_index_endpoint.IndexEndpoint( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].index_endpoint + mock_val = gca_index_endpoint.IndexEndpoint(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -774,6 +778,7 @@ def test_get_index_endpoint( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, ) response = client.get_index_endpoint(request) @@ -789,6 +794,7 @@ def test_get_index_endpoint( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True def test_get_index_endpoint_from_dict(): @@ -837,6 +843,7 @@ async def test_get_index_endpoint_async( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, ) ) response = await client.get_index_endpoint(request) @@ -853,6 +860,7 @@ async def test_get_index_endpoint_async( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True @pytest.mark.asyncio @@ -938,7 +946,9 @@ def test_get_index_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_index_endpoint_flattened_error(): @@ -978,7 +988,9 @@ async def test_get_index_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1166,7 +1178,9 @@ def test_list_index_endpoints_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_index_endpoints_flattened_error(): @@ -1206,7 +1220,9 @@ async def test_list_index_endpoints_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1424,6 +1440,7 @@ def test_update_index_endpoint( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, ) response = client.update_index_endpoint(request) @@ -1439,6 +1456,7 @@ def test_update_index_endpoint( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True def test_update_index_endpoint_from_dict(): @@ -1487,6 +1505,7 @@ async def test_update_index_endpoint_async( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, ) ) response = await client.update_index_endpoint(request) @@ -1503,6 +1522,7 @@ async def test_update_index_endpoint_async( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True @pytest.mark.asyncio @@ -1597,10 +1617,12 @@ def test_update_index_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == gca_index_endpoint.IndexEndpoint( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].index_endpoint + mock_val = gca_index_endpoint.IndexEndpoint(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_index_endpoint_flattened_error(): @@ -1645,10 +1667,12 @@ async def test_update_index_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == gca_index_endpoint.IndexEndpoint( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].index_endpoint + mock_val = gca_index_endpoint.IndexEndpoint(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 @@ -1832,7 +1856,9 @@ def test_delete_index_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_index_endpoint_flattened_error(): @@ -1872,7 +1898,9 @@ async def test_delete_index_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2048,8 +2076,12 @@ def test_deploy_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == "index_endpoint_value" - assert args[0].deployed_index == gca_index_endpoint.DeployedIndex(id="id_value") + arg = args[0].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index + mock_val = gca_index_endpoint.DeployedIndex(id="id_value") + assert arg == mock_val def test_deploy_index_flattened_error(): @@ -2092,8 +2124,12 @@ async def test_deploy_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == "index_endpoint_value" - assert args[0].deployed_index == gca_index_endpoint.DeployedIndex(id="id_value") + arg = args[0].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index + mock_val = gca_index_endpoint.DeployedIndex(id="id_value") + assert arg == mock_val @pytest.mark.asyncio @@ -2271,8 +2307,12 @@ def test_undeploy_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == "index_endpoint_value" - assert args[0].deployed_index_id == "deployed_index_id_value" + arg = args[0].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index_id + mock_val = "deployed_index_id_value" + assert arg == mock_val def test_undeploy_index_flattened_error(): @@ -2315,8 +2355,12 @@ async def test_undeploy_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == "index_endpoint_value" - assert args[0].deployed_index_id == "deployed_index_id_value" + arg = args[0].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index_id + mock_val = "deployed_index_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2335,6 +2379,252 @@ async def test_undeploy_index_flattened_error_async(): ) +def test_mutate_deployed_index( + transport: str = "grpc", + request_type=index_endpoint_service.MutateDeployedIndexRequest, +): + client = IndexEndpointServiceClient( + 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.mutate_deployed_index), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.mutate_deployed_index(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == index_endpoint_service.MutateDeployedIndexRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_mutate_deployed_index_from_dict(): + test_mutate_deployed_index(request_type=dict) + + +def test_mutate_deployed_index_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = IndexEndpointServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__call__" + ) as call: + client.mutate_deployed_index() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == index_endpoint_service.MutateDeployedIndexRequest() + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_async( + transport: str = "grpc_asyncio", + request_type=index_endpoint_service.MutateDeployedIndexRequest, +): + client = IndexEndpointServiceAsyncClient( + 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.mutate_deployed_index), "__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.mutate_deployed_index(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == index_endpoint_service.MutateDeployedIndexRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_async_from_dict(): + await test_mutate_deployed_index_async(request_type=dict) + + +def test_mutate_deployed_index_field_headers(): + client = IndexEndpointServiceClient( + 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 = index_endpoint_service.MutateDeployedIndexRequest() + + request.index_endpoint = "index_endpoint/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.mutate_deployed_index(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", "index_endpoint=index_endpoint/value",) in kw[ + "metadata" + ] + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_field_headers_async(): + client = IndexEndpointServiceAsyncClient( + 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 = index_endpoint_service.MutateDeployedIndexRequest() + + request.index_endpoint = "index_endpoint/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.mutate_deployed_index(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", "index_endpoint=index_endpoint/value",) in kw[ + "metadata" + ] + + +def test_mutate_deployed_index_flattened(): + client = IndexEndpointServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__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.mutate_deployed_index( + index_endpoint="index_endpoint_value", + deployed_index=gca_index_endpoint.DeployedIndex(id="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].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index + mock_val = gca_index_endpoint.DeployedIndex(id="id_value") + assert arg == mock_val + + +def test_mutate_deployed_index_flattened_error(): + client = IndexEndpointServiceClient( + 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.mutate_deployed_index( + index_endpoint_service.MutateDeployedIndexRequest(), + index_endpoint="index_endpoint_value", + deployed_index=gca_index_endpoint.DeployedIndex(id="id_value"), + ) + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_flattened_async(): + client = IndexEndpointServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__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.mutate_deployed_index( + index_endpoint="index_endpoint_value", + deployed_index=gca_index_endpoint.DeployedIndex(id="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].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index + mock_val = gca_index_endpoint.DeployedIndex(id="id_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_flattened_error_async(): + client = IndexEndpointServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.mutate_deployed_index( + index_endpoint_service.MutateDeployedIndexRequest(), + index_endpoint="index_endpoint_value", + deployed_index=gca_index_endpoint.DeployedIndex(id="id_value"), + ) + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.IndexEndpointServiceGrpcTransport( @@ -2441,6 +2731,7 @@ def test_index_endpoint_service_base_transport(): "delete_index_endpoint", "deploy_index", "undeploy_index", + "mutate_deployed_index", ) for method in methods: with pytest.raises(NotImplementedError): diff --git a/tests/unit/gapic/aiplatform_v1/test_index_service.py b/tests/unit/gapic/aiplatform_v1/test_index_service.py index 3b5ac0574a..56ace1aee2 100644 --- a/tests/unit/gapic/aiplatform_v1/test_index_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_index_service.py @@ -622,8 +622,12 @@ def test_create_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].index == gca_index.Index(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].index + mock_val = gca_index.Index(name="name_value") + assert arg == mock_val def test_create_index_flattened_error(): @@ -661,8 +665,12 @@ async def test_create_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].index == gca_index.Index(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].index + mock_val = gca_index.Index(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -842,7 +850,9 @@ def test_get_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_index_flattened_error(): @@ -874,7 +884,9 @@ async def test_get_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1038,7 +1050,9 @@ def test_list_indexes_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_indexes_flattened_error(): @@ -1072,7 +1086,9 @@ async def test_list_indexes_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1349,8 +1365,12 @@ def test_update_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].index == gca_index.Index(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].index + mock_val = gca_index.Index(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_index_flattened_error(): @@ -1389,8 +1409,12 @@ async def test_update_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].index == gca_index.Index(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].index + mock_val = gca_index.Index(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 @@ -1552,7 +1576,9 @@ def test_delete_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_index_flattened_error(): @@ -1586,7 +1612,9 @@ async def test_delete_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_job_service.py b/tests/unit/gapic/aiplatform_v1/test_job_service.py index 01a43116bd..0a0221dc28 100644 --- a/tests/unit/gapic/aiplatform_v1/test_job_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_job_service.py @@ -61,6 +61,7 @@ from google.cloud.aiplatform_v1.types import job_state from google.cloud.aiplatform_v1.types import machine_resources from google.cloud.aiplatform_v1.types import manual_batch_tuning_parameters +from google.cloud.aiplatform_v1.types import model from google.cloud.aiplatform_v1.types import model_deployment_monitoring_job from google.cloud.aiplatform_v1.types import ( model_deployment_monitoring_job as gca_model_deployment_monitoring_job, @@ -68,6 +69,7 @@ from google.cloud.aiplatform_v1.types import model_monitoring from google.cloud.aiplatform_v1.types import operation as gca_operation from google.cloud.aiplatform_v1.types import study +from google.cloud.aiplatform_v1.types import unmanaged_container_model from google.longrunning import operations_pb2 from google.oauth2 import service_account from google.protobuf import any_pb2 # type: ignore @@ -678,8 +680,12 @@ def test_create_custom_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].custom_job == gca_custom_job.CustomJob(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].custom_job + mock_val = gca_custom_job.CustomJob(name="name_value") + assert arg == mock_val def test_create_custom_job_flattened_error(): @@ -720,8 +726,12 @@ async def test_create_custom_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].custom_job == gca_custom_job.CustomJob(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].custom_job + mock_val = gca_custom_job.CustomJob(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -897,7 +907,9 @@ def test_get_custom_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_custom_job_flattened_error(): @@ -931,7 +943,9 @@ async def test_get_custom_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1095,7 +1109,9 @@ def test_list_custom_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_custom_jobs_flattened_error(): @@ -1129,7 +1145,9 @@ async def test_list_custom_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1439,7 +1457,9 @@ def test_delete_custom_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_custom_job_flattened_error(): @@ -1475,7 +1495,9 @@ async def test_delete_custom_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1643,7 +1665,9 @@ def test_cancel_custom_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_custom_job_flattened_error(): @@ -1677,7 +1701,9 @@ async def test_cancel_custom_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1891,10 +1917,12 @@ def test_create_data_labeling_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].data_labeling_job == gca_data_labeling_job.DataLabelingJob( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].data_labeling_job + mock_val = gca_data_labeling_job.DataLabelingJob(name="name_value") + assert arg == mock_val def test_create_data_labeling_job_flattened_error(): @@ -1935,10 +1963,12 @@ async def test_create_data_labeling_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].data_labeling_job == gca_data_labeling_job.DataLabelingJob( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].data_labeling_job + mock_val = gca_data_labeling_job.DataLabelingJob(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -2150,7 +2180,9 @@ def test_get_data_labeling_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_data_labeling_job_flattened_error(): @@ -2186,7 +2218,9 @@ async def test_get_data_labeling_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2365,7 +2399,9 @@ def test_list_data_labeling_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_data_labeling_jobs_flattened_error(): @@ -2401,7 +2437,9 @@ async def test_list_data_labeling_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2744,7 +2782,9 @@ def test_delete_data_labeling_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_data_labeling_job_flattened_error(): @@ -2780,7 +2820,9 @@ async def test_delete_data_labeling_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2949,7 +2991,9 @@ def test_cancel_data_labeling_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_data_labeling_job_flattened_error(): @@ -2983,7 +3027,9 @@ async def test_cancel_data_labeling_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3188,12 +3234,14 @@ def test_create_hyperparameter_tuning_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].hyperparameter_tuning_job == gca_hyperparameter_tuning_job.HyperparameterTuningJob( + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].hyperparameter_tuning_job + mock_val = gca_hyperparameter_tuning_job.HyperparameterTuningJob( name="name_value" ) + assert arg == mock_val def test_create_hyperparameter_tuning_job_flattened_error(): @@ -3238,12 +3286,14 @@ async def test_create_hyperparameter_tuning_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].hyperparameter_tuning_job == gca_hyperparameter_tuning_job.HyperparameterTuningJob( + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].hyperparameter_tuning_job + mock_val = gca_hyperparameter_tuning_job.HyperparameterTuningJob( name="name_value" ) + assert arg == mock_val @pytest.mark.asyncio @@ -3446,7 +3496,9 @@ def test_get_hyperparameter_tuning_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_hyperparameter_tuning_job_flattened_error(): @@ -3482,7 +3534,9 @@ async def test_get_hyperparameter_tuning_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3662,7 +3716,9 @@ def test_list_hyperparameter_tuning_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_hyperparameter_tuning_jobs_flattened_error(): @@ -3698,7 +3754,9 @@ async def test_list_hyperparameter_tuning_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4058,7 +4116,9 @@ def test_delete_hyperparameter_tuning_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_hyperparameter_tuning_job_flattened_error(): @@ -4094,7 +4154,9 @@ async def test_delete_hyperparameter_tuning_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4264,7 +4326,9 @@ def test_cancel_hyperparameter_tuning_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_hyperparameter_tuning_job_flattened_error(): @@ -4298,7 +4362,9 @@ async def test_cancel_hyperparameter_tuning_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4498,12 +4564,12 @@ def test_create_batch_prediction_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].batch_prediction_job == gca_batch_prediction_job.BatchPredictionJob( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].batch_prediction_job + mock_val = gca_batch_prediction_job.BatchPredictionJob(name="name_value") + assert arg == mock_val def test_create_batch_prediction_job_flattened_error(): @@ -4548,12 +4614,12 @@ async def test_create_batch_prediction_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].batch_prediction_job == gca_batch_prediction_job.BatchPredictionJob( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].batch_prediction_job + mock_val = gca_batch_prediction_job.BatchPredictionJob(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -4752,7 +4818,9 @@ def test_get_batch_prediction_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_batch_prediction_job_flattened_error(): @@ -4788,7 +4856,9 @@ async def test_get_batch_prediction_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4967,7 +5037,9 @@ def test_list_batch_prediction_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_batch_prediction_jobs_flattened_error(): @@ -5003,7 +5075,9 @@ async def test_list_batch_prediction_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5350,7 +5424,9 @@ def test_delete_batch_prediction_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_batch_prediction_job_flattened_error(): @@ -5386,7 +5462,9 @@ async def test_delete_batch_prediction_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5555,7 +5633,9 @@ def test_cancel_batch_prediction_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_batch_prediction_job_flattened_error(): @@ -5589,7 +5669,9 @@ async def test_cancel_batch_prediction_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5816,12 +5898,14 @@ def test_create_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].model_deployment_monitoring_job == gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model_deployment_monitoring_job + mock_val = gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( name="name_value" ) + assert arg == mock_val def test_create_model_deployment_monitoring_job_flattened_error(): @@ -5868,12 +5952,14 @@ async def test_create_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].model_deployment_monitoring_job == gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model_deployment_monitoring_job + mock_val = gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( name="name_value" ) + assert arg == mock_val @pytest.mark.asyncio @@ -6093,11 +6179,12 @@ def test_search_model_deployment_monitoring_stats_anomalies_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert ( - args[0].model_deployment_monitoring_job - == "model_deployment_monitoring_job_value" - ) - assert args[0].deployed_model_id == "deployed_model_id_value" + arg = args[0].model_deployment_monitoring_job + mock_val = "model_deployment_monitoring_job_value" + assert arg == mock_val + arg = args[0].deployed_model_id + mock_val = "deployed_model_id_value" + assert arg == mock_val def test_search_model_deployment_monitoring_stats_anomalies_flattened_error(): @@ -6141,11 +6228,12 @@ async def test_search_model_deployment_monitoring_stats_anomalies_flattened_asyn # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert ( - args[0].model_deployment_monitoring_job - == "model_deployment_monitoring_job_value" - ) - assert args[0].deployed_model_id == "deployed_model_id_value" + arg = args[0].model_deployment_monitoring_job + mock_val = "model_deployment_monitoring_job_value" + assert arg == mock_val + arg = args[0].deployed_model_id + mock_val = "deployed_model_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6567,7 +6655,9 @@ def test_get_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_model_deployment_monitoring_job_flattened_error(): @@ -6605,7 +6695,9 @@ async def test_get_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6785,7 +6877,9 @@ def test_list_model_deployment_monitoring_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_model_deployment_monitoring_jobs_flattened_error(): @@ -6824,7 +6918,9 @@ async def test_list_model_deployment_monitoring_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7200,12 +7296,14 @@ def test_update_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[ - 0 - ].model_deployment_monitoring_job == gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( + arg = args[0].model_deployment_monitoring_job + mock_val = gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( name="name_value" ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val def test_update_model_deployment_monitoring_job_flattened_error(): @@ -7250,12 +7348,14 @@ async def test_update_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[ - 0 - ].model_deployment_monitoring_job == gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( + arg = args[0].model_deployment_monitoring_job + mock_val = gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( name="name_value" ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_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 @@ -7433,7 +7533,9 @@ def test_delete_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_model_deployment_monitoring_job_flattened_error(): @@ -7471,7 +7573,9 @@ async def test_delete_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7641,7 +7745,9 @@ def test_pause_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_pause_model_deployment_monitoring_job_flattened_error(): @@ -7677,7 +7783,9 @@ async def test_pause_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7847,7 +7955,9 @@ def test_resume_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_resume_model_deployment_monitoring_job_flattened_error(): @@ -7883,7 +7993,9 @@ async def test_resume_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -8559,11 +8671,35 @@ def test_parse_network_path(): assert expected == actual -def test_trial_path(): +def test_tensorboard_path(): project = "oyster" location = "nudibranch" - study = "cuttlefish" - trial = "mussel" + tensorboard = "cuttlefish" + expected = "projects/{project}/locations/{location}/tensorboards/{tensorboard}".format( + project=project, location=location, tensorboard=tensorboard, + ) + actual = JobServiceClient.tensorboard_path(project, location, tensorboard) + assert expected == actual + + +def test_parse_tensorboard_path(): + expected = { + "project": "mussel", + "location": "winkle", + "tensorboard": "nautilus", + } + path = JobServiceClient.tensorboard_path(**expected) + + # Check that the path construction is reversible. + actual = JobServiceClient.parse_tensorboard_path(path) + assert expected == actual + + +def test_trial_path(): + project = "scallop" + location = "abalone" + study = "squid" + trial = "clam" expected = "projects/{project}/locations/{location}/studies/{study}/trials/{trial}".format( project=project, location=location, study=study, trial=trial, ) @@ -8573,10 +8709,10 @@ def test_trial_path(): def test_parse_trial_path(): expected = { - "project": "winkle", - "location": "nautilus", - "study": "scallop", - "trial": "abalone", + "project": "whelk", + "location": "octopus", + "study": "oyster", + "trial": "nudibranch", } path = JobServiceClient.trial_path(**expected) @@ -8586,7 +8722,7 @@ def test_parse_trial_path(): def test_common_billing_account_path(): - billing_account = "squid" + billing_account = "cuttlefish" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -8596,7 +8732,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "clam", + "billing_account": "mussel", } path = JobServiceClient.common_billing_account_path(**expected) @@ -8606,7 +8742,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "whelk" + folder = "winkle" expected = "folders/{folder}".format(folder=folder,) actual = JobServiceClient.common_folder_path(folder) assert expected == actual @@ -8614,7 +8750,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "octopus", + "folder": "nautilus", } path = JobServiceClient.common_folder_path(**expected) @@ -8624,7 +8760,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "oyster" + organization = "scallop" expected = "organizations/{organization}".format(organization=organization,) actual = JobServiceClient.common_organization_path(organization) assert expected == actual @@ -8632,7 +8768,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "nudibranch", + "organization": "abalone", } path = JobServiceClient.common_organization_path(**expected) @@ -8642,7 +8778,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "cuttlefish" + project = "squid" expected = "projects/{project}".format(project=project,) actual = JobServiceClient.common_project_path(project) assert expected == actual @@ -8650,7 +8786,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "mussel", + "project": "clam", } path = JobServiceClient.common_project_path(**expected) @@ -8660,8 +8796,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "winkle" - location = "nautilus" + project = "whelk" + location = "octopus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -8671,8 +8807,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "scallop", - "location": "abalone", + "project": "oyster", + "location": "nudibranch", } path = JobServiceClient.common_location_path(**expected) diff --git a/tests/unit/gapic/aiplatform_v1/test_metadata_service.py b/tests/unit/gapic/aiplatform_v1/test_metadata_service.py index 1fecc7b130..472a3f0949 100644 --- a/tests/unit/gapic/aiplatform_v1/test_metadata_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_metadata_service.py @@ -674,11 +674,15 @@ def test_create_metadata_store_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].metadata_store == gca_metadata_store.MetadataStore( - name="name_value" - ) - assert args[0].metadata_store_id == "metadata_store_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].metadata_store + mock_val = gca_metadata_store.MetadataStore(name="name_value") + assert arg == mock_val + arg = args[0].metadata_store_id + mock_val = "metadata_store_id_value" + assert arg == mock_val def test_create_metadata_store_flattened_error(): @@ -723,11 +727,15 @@ async def test_create_metadata_store_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].metadata_store == gca_metadata_store.MetadataStore( - name="name_value" - ) - assert args[0].metadata_store_id == "metadata_store_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].metadata_store + mock_val = gca_metadata_store.MetadataStore(name="name_value") + assert arg == mock_val + arg = args[0].metadata_store_id + mock_val = "metadata_store_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -915,7 +923,9 @@ def test_get_metadata_store_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_metadata_store_flattened_error(): @@ -953,7 +963,9 @@ async def test_get_metadata_store_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1136,7 +1148,9 @@ def test_list_metadata_stores_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_metadata_stores_flattened_error(): @@ -1174,7 +1188,9 @@ async def test_list_metadata_stores_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1525,7 +1541,9 @@ def test_delete_metadata_store_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_metadata_store_flattened_error(): @@ -1563,7 +1581,9 @@ async def test_delete_metadata_store_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1765,9 +1785,15 @@ def test_create_artifact_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].artifact == gca_artifact.Artifact(name="name_value") - assert args[0].artifact_id == "artifact_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].artifact + mock_val = gca_artifact.Artifact(name="name_value") + assert arg == mock_val + arg = args[0].artifact_id + mock_val = "artifact_id_value" + assert arg == mock_val def test_create_artifact_flattened_error(): @@ -1810,9 +1836,15 @@ async def test_create_artifact_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].artifact == gca_artifact.Artifact(name="name_value") - assert args[0].artifact_id == "artifact_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].artifact + mock_val = gca_artifact.Artifact(name="name_value") + assert arg == mock_val + arg = args[0].artifact_id + mock_val = "artifact_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2011,7 +2043,9 @@ def test_get_artifact_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_artifact_flattened_error(): @@ -2045,7 +2079,9 @@ async def test_get_artifact_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2215,7 +2251,9 @@ def test_list_artifacts_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_artifacts_flattened_error(): @@ -2251,7 +2289,9 @@ async def test_list_artifacts_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2606,8 +2646,12 @@ def test_update_artifact_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].artifact == gca_artifact.Artifact(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].artifact + mock_val = gca_artifact.Artifact(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_artifact_flattened_error(): @@ -2648,8 +2692,12 @@ async def test_update_artifact_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].artifact == gca_artifact.Artifact(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].artifact + mock_val = gca_artifact.Artifact(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 @@ -2815,7 +2863,9 @@ def test_delete_artifact_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_artifact_flattened_error(): @@ -2851,7 +2901,9 @@ async def test_delete_artifact_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3015,7 +3067,9 @@ def test_purge_artifacts_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_purge_artifacts_flattened_error(): @@ -3051,7 +3105,9 @@ async def test_purge_artifacts_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3247,9 +3303,15 @@ def test_create_context_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].context == gca_context.Context(name="name_value") - assert args[0].context_id == "context_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].context + mock_val = gca_context.Context(name="name_value") + assert arg == mock_val + arg = args[0].context_id + mock_val = "context_id_value" + assert arg == mock_val def test_create_context_flattened_error(): @@ -3290,9 +3352,15 @@ async def test_create_context_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].context == gca_context.Context(name="name_value") - assert args[0].context_id == "context_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].context + mock_val = gca_context.Context(name="name_value") + assert arg == mock_val + arg = args[0].context_id + mock_val = "context_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3487,7 +3555,9 @@ def test_get_context_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_context_flattened_error(): @@ -3521,7 +3591,9 @@ async def test_get_context_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3691,7 +3763,9 @@ def test_list_contexts_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_contexts_flattened_error(): @@ -3727,7 +3801,9 @@ async def test_list_contexts_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4052,8 +4128,12 @@ def test_update_context_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].context == gca_context.Context(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].context + mock_val = gca_context.Context(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_context_flattened_error(): @@ -4092,8 +4172,12 @@ async def test_update_context_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].context == gca_context.Context(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].context + mock_val = gca_context.Context(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 @@ -4259,7 +4343,9 @@ def test_delete_context_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_context_flattened_error(): @@ -4295,7 +4381,9 @@ async def test_delete_context_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4459,7 +4547,9 @@ def test_purge_contexts_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_purge_contexts_flattened_error(): @@ -4495,7 +4585,9 @@ async def test_purge_contexts_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4681,9 +4773,15 @@ def test_add_context_artifacts_and_executions_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" - assert args[0].artifacts == ["artifacts_value"] - assert args[0].executions == ["executions_value"] + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val + arg = args[0].artifacts + mock_val = ["artifacts_value"] + assert arg == mock_val + arg = args[0].executions + mock_val = ["executions_value"] + assert arg == mock_val def test_add_context_artifacts_and_executions_flattened_error(): @@ -4728,9 +4826,15 @@ async def test_add_context_artifacts_and_executions_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" - assert args[0].artifacts == ["artifacts_value"] - assert args[0].executions == ["executions_value"] + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val + arg = args[0].artifacts + mock_val = ["artifacts_value"] + assert arg == mock_val + arg = args[0].executions + mock_val = ["executions_value"] + assert arg == mock_val @pytest.mark.asyncio @@ -4912,8 +5016,12 @@ def test_add_context_children_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" - assert args[0].child_contexts == ["child_contexts_value"] + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val + arg = args[0].child_contexts + mock_val = ["child_contexts_value"] + assert arg == mock_val def test_add_context_children_flattened_error(): @@ -4955,8 +5063,12 @@ async def test_add_context_children_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" - assert args[0].child_contexts == ["child_contexts_value"] + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val + arg = args[0].child_contexts + mock_val = ["child_contexts_value"] + assert arg == mock_val @pytest.mark.asyncio @@ -5136,7 +5248,9 @@ def test_query_context_lineage_subgraph_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val def test_query_context_lineage_subgraph_flattened_error(): @@ -5175,7 +5289,9 @@ async def test_query_context_lineage_subgraph_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5375,9 +5491,15 @@ def test_create_execution_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].execution == gca_execution.Execution(name="name_value") - assert args[0].execution_id == "execution_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].execution + mock_val = gca_execution.Execution(name="name_value") + assert arg == mock_val + arg = args[0].execution_id + mock_val = "execution_id_value" + assert arg == mock_val def test_create_execution_flattened_error(): @@ -5420,9 +5542,15 @@ async def test_create_execution_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].execution == gca_execution.Execution(name="name_value") - assert args[0].execution_id == "execution_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].execution + mock_val = gca_execution.Execution(name="name_value") + assert arg == mock_val + arg = args[0].execution_id + mock_val = "execution_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5617,7 +5745,9 @@ def test_get_execution_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_execution_flattened_error(): @@ -5651,7 +5781,9 @@ async def test_get_execution_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5821,7 +5953,9 @@ def test_list_executions_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_executions_flattened_error(): @@ -5857,7 +5991,9 @@ async def test_list_executions_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6209,8 +6345,12 @@ def test_update_execution_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].execution == gca_execution.Execution(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].execution + mock_val = gca_execution.Execution(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_execution_flattened_error(): @@ -6251,8 +6391,12 @@ async def test_update_execution_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].execution == gca_execution.Execution(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].execution + mock_val = gca_execution.Execution(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 @@ -6419,7 +6563,9 @@ def test_delete_execution_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_execution_flattened_error(): @@ -6455,7 +6601,9 @@ async def test_delete_execution_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6620,7 +6768,9 @@ def test_purge_executions_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_purge_executions_flattened_error(): @@ -6656,7 +6806,9 @@ async def test_purge_executions_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6836,8 +6988,12 @@ def test_add_execution_events_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].execution == "execution_value" - assert args[0].events == [event.Event(artifact="artifact_value")] + arg = args[0].execution + mock_val = "execution_value" + assert arg == mock_val + arg = args[0].events + mock_val = [event.Event(artifact="artifact_value")] + assert arg == mock_val def test_add_execution_events_flattened_error(): @@ -6880,8 +7036,12 @@ async def test_add_execution_events_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].execution == "execution_value" - assert args[0].events == [event.Event(artifact="artifact_value")] + arg = args[0].execution + mock_val = "execution_value" + assert arg == mock_val + arg = args[0].events + mock_val = [event.Event(artifact="artifact_value")] + assert arg == mock_val @pytest.mark.asyncio @@ -7061,7 +7221,9 @@ def test_query_execution_inputs_and_outputs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].execution == "execution_value" + arg = args[0].execution + mock_val = "execution_value" + assert arg == mock_val def test_query_execution_inputs_and_outputs_flattened_error(): @@ -7102,7 +7264,9 @@ async def test_query_execution_inputs_and_outputs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].execution == "execution_value" + arg = args[0].execution + mock_val = "execution_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7312,11 +7476,15 @@ def test_create_metadata_schema_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].metadata_schema == gca_metadata_schema.MetadataSchema( - name="name_value" - ) - assert args[0].metadata_schema_id == "metadata_schema_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].metadata_schema + mock_val = gca_metadata_schema.MetadataSchema(name="name_value") + assert arg == mock_val + arg = args[0].metadata_schema_id + mock_val = "metadata_schema_id_value" + assert arg == mock_val def test_create_metadata_schema_flattened_error(): @@ -7361,11 +7529,15 @@ async def test_create_metadata_schema_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].metadata_schema == gca_metadata_schema.MetadataSchema( - name="name_value" - ) - assert args[0].metadata_schema_id == "metadata_schema_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].metadata_schema + mock_val = gca_metadata_schema.MetadataSchema(name="name_value") + assert arg == mock_val + arg = args[0].metadata_schema_id + mock_val = "metadata_schema_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7573,7 +7745,9 @@ def test_get_metadata_schema_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_metadata_schema_flattened_error(): @@ -7611,7 +7785,9 @@ async def test_get_metadata_schema_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7794,7 +7970,9 @@ def test_list_metadata_schemas_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_metadata_schemas_flattened_error(): @@ -7832,7 +8010,9 @@ async def test_list_metadata_schemas_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -8184,7 +8364,9 @@ def test_query_artifact_lineage_subgraph_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].artifact == "artifact_value" + arg = args[0].artifact + mock_val = "artifact_value" + assert arg == mock_val def test_query_artifact_lineage_subgraph_flattened_error(): @@ -8225,7 +8407,9 @@ async def test_query_artifact_lineage_subgraph_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].artifact == "artifact_value" + arg = args[0].artifact + mock_val = "artifact_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_migration_service.py b/tests/unit/gapic/aiplatform_v1/test_migration_service.py index 3a57f1775f..15277d3072 100644 --- a/tests/unit/gapic/aiplatform_v1/test_migration_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_migration_service.py @@ -662,7 +662,9 @@ def test_search_migratable_resources_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_search_migratable_resources_flattened_error(): @@ -700,7 +702,9 @@ async def test_search_migratable_resources_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1064,14 +1068,18 @@ def test_batch_migrate_resources_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].migrate_resource_requests == [ + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].migrate_resource_requests + mock_val = [ migration_service.MigrateResourceRequest( migrate_ml_engine_model_version_config=migration_service.MigrateResourceRequest.MigrateMlEngineModelVersionConfig( endpoint="endpoint_value" ) ) ] + assert arg == mock_val def test_batch_migrate_resources_flattened_error(): @@ -1126,14 +1134,18 @@ async def test_batch_migrate_resources_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].migrate_resource_requests == [ + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].migrate_resource_requests + mock_val = [ migration_service.MigrateResourceRequest( migrate_ml_engine_model_version_config=migration_service.MigrateResourceRequest.MigrateMlEngineModelVersionConfig( endpoint="endpoint_value" ) ) ] + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_model_service.py b/tests/unit/gapic/aiplatform_v1/test_model_service.py index 993626996f..d3252ec4eb 100644 --- a/tests/unit/gapic/aiplatform_v1/test_model_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_model_service.py @@ -629,8 +629,12 @@ def test_upload_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].model == gca_model.Model(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model + mock_val = gca_model.Model(name="name_value") + assert arg == mock_val def test_upload_model_flattened_error(): @@ -668,8 +672,12 @@ async def test_upload_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].model == gca_model.Model(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model + mock_val = gca_model.Model(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -889,7 +897,9 @@ def test_get_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_model_flattened_error(): @@ -921,7 +931,9 @@ async def test_get_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1085,7 +1097,9 @@ def test_list_models_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_models_flattened_error(): @@ -1119,7 +1133,9 @@ async def test_list_models_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1456,8 +1472,12 @@ def test_update_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].model == gca_model.Model(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].model + mock_val = gca_model.Model(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val def test_update_model_flattened_error(): @@ -1494,8 +1514,12 @@ async def test_update_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].model == gca_model.Model(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].model + mock_val = gca_model.Model(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val @pytest.mark.asyncio @@ -1657,7 +1681,9 @@ def test_delete_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_model_flattened_error(): @@ -1691,7 +1717,9 @@ async def test_delete_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1856,10 +1884,14 @@ def test_export_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].output_config == model_service.ExportModelRequest.OutputConfig( + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].output_config + mock_val = model_service.ExportModelRequest.OutputConfig( export_format_id="export_format_id_value" ) + assert arg == mock_val def test_export_model_flattened_error(): @@ -1902,10 +1934,14 @@ async def test_export_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].output_config == model_service.ExportModelRequest.OutputConfig( + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].output_config + mock_val = model_service.ExportModelRequest.OutputConfig( export_format_id="export_format_id_value" ) + assert arg == mock_val @pytest.mark.asyncio @@ -2096,7 +2132,9 @@ def test_get_model_evaluation_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_model_evaluation_flattened_error(): @@ -2132,7 +2170,9 @@ async def test_get_model_evaluation_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2311,7 +2351,9 @@ def test_list_model_evaluations_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_model_evaluations_flattened_error(): @@ -2347,7 +2389,9 @@ async def test_list_model_evaluations_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2698,7 +2742,9 @@ def test_get_model_evaluation_slice_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_model_evaluation_slice_flattened_error(): @@ -2734,7 +2780,9 @@ async def test_get_model_evaluation_slice_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2913,7 +2961,9 @@ def test_list_model_evaluation_slices_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_model_evaluation_slices_flattened_error(): @@ -2949,7 +2999,9 @@ async def test_list_model_evaluation_slices_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_pipeline_service.py b/tests/unit/gapic/aiplatform_v1/test_pipeline_service.py index 85bb176bb9..8889588489 100644 --- a/tests/unit/gapic/aiplatform_v1/test_pipeline_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_pipeline_service.py @@ -696,10 +696,12 @@ def test_create_training_pipeline_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].training_pipeline == gca_training_pipeline.TrainingPipeline( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].training_pipeline + mock_val = gca_training_pipeline.TrainingPipeline(name="name_value") + assert arg == mock_val def test_create_training_pipeline_flattened_error(): @@ -742,10 +744,12 @@ async def test_create_training_pipeline_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].training_pipeline == gca_training_pipeline.TrainingPipeline( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].training_pipeline + mock_val = gca_training_pipeline.TrainingPipeline(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -942,7 +946,9 @@ def test_get_training_pipeline_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_training_pipeline_flattened_error(): @@ -980,7 +986,9 @@ async def test_get_training_pipeline_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1163,7 +1171,9 @@ def test_list_training_pipelines_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_training_pipelines_flattened_error(): @@ -1201,7 +1211,9 @@ async def test_list_training_pipelines_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1552,7 +1564,9 @@ def test_delete_training_pipeline_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_training_pipeline_flattened_error(): @@ -1590,7 +1604,9 @@ async def test_delete_training_pipeline_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1763,7 +1779,9 @@ def test_cancel_training_pipeline_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_training_pipeline_flattened_error(): @@ -1799,7 +1817,9 @@ async def test_cancel_training_pipeline_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2002,9 +2022,15 @@ def test_create_pipeline_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].pipeline_job == gca_pipeline_job.PipelineJob(name="name_value") - assert args[0].pipeline_job_id == "pipeline_job_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].pipeline_job + mock_val = gca_pipeline_job.PipelineJob(name="name_value") + assert arg == mock_val + arg = args[0].pipeline_job_id + mock_val = "pipeline_job_id_value" + assert arg == mock_val def test_create_pipeline_job_flattened_error(): @@ -2049,9 +2075,15 @@ async def test_create_pipeline_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].pipeline_job == gca_pipeline_job.PipelineJob(name="name_value") - assert args[0].pipeline_job_id == "pipeline_job_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].pipeline_job + mock_val = gca_pipeline_job.PipelineJob(name="name_value") + assert arg == mock_val + arg = args[0].pipeline_job_id + mock_val = "pipeline_job_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2240,7 +2272,9 @@ def test_get_pipeline_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_pipeline_job_flattened_error(): @@ -2276,7 +2310,9 @@ async def test_get_pipeline_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2459,7 +2495,9 @@ def test_list_pipeline_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_pipeline_jobs_flattened_error(): @@ -2497,7 +2535,9 @@ async def test_list_pipeline_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2832,7 +2872,9 @@ def test_delete_pipeline_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_pipeline_job_flattened_error(): @@ -2870,7 +2912,9 @@ async def test_delete_pipeline_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3043,7 +3087,9 @@ def test_cancel_pipeline_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_pipeline_job_flattened_error(): @@ -3079,7 +3125,9 @@ async def test_cancel_pipeline_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_prediction_service.py b/tests/unit/gapic/aiplatform_v1/test_prediction_service.py index 3aa6e11f0a..8278921b19 100644 --- a/tests/unit/gapic/aiplatform_v1/test_prediction_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_prediction_service.py @@ -828,10 +828,12 @@ def test_raw_predict_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].http_body == httpbody_pb2.HttpBody( - content_type="content_type_value" - ) + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].http_body + mock_val = httpbody_pb2.HttpBody(content_type="content_type_value") + assert arg == mock_val def test_raw_predict_flattened_error(): @@ -872,10 +874,12 @@ async def test_raw_predict_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].http_body == httpbody_pb2.HttpBody( - content_type="content_type_value" - ) + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].http_body + mock_val = httpbody_pb2.HttpBody(content_type="content_type_value") + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1/test_specialist_pool_service.py b/tests/unit/gapic/aiplatform_v1/test_specialist_pool_service.py index 5967720839..4bf3404939 100644 --- a/tests/unit/gapic/aiplatform_v1/test_specialist_pool_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_specialist_pool_service.py @@ -680,10 +680,12 @@ def test_create_specialist_pool_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].specialist_pool == gca_specialist_pool.SpecialistPool( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].specialist_pool + mock_val = gca_specialist_pool.SpecialistPool(name="name_value") + assert arg == mock_val def test_create_specialist_pool_flattened_error(): @@ -728,10 +730,12 @@ async def test_create_specialist_pool_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].specialist_pool == gca_specialist_pool.SpecialistPool( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].specialist_pool + mock_val = gca_specialist_pool.SpecialistPool(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -941,7 +945,9 @@ def test_get_specialist_pool_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_specialist_pool_flattened_error(): @@ -981,7 +987,9 @@ async def test_get_specialist_pool_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1169,7 +1177,9 @@ def test_list_specialist_pools_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_specialist_pools_flattened_error(): @@ -1209,7 +1219,9 @@ async def test_list_specialist_pools_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1569,7 +1581,9 @@ def test_delete_specialist_pool_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_specialist_pool_flattened_error(): @@ -1609,7 +1623,9 @@ async def test_delete_specialist_pool_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1800,10 +1816,12 @@ def test_update_specialist_pool_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].specialist_pool == gca_specialist_pool.SpecialistPool( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].specialist_pool + mock_val = gca_specialist_pool.SpecialistPool(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_specialist_pool_flattened_error(): @@ -1848,10 +1866,12 @@ async def test_update_specialist_pool_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].specialist_pool == gca_specialist_pool.SpecialistPool( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].specialist_pool + mock_val = gca_specialist_pool.SpecialistPool(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 diff --git a/tests/unit/gapic/aiplatform_v1/test_tensorboard_service.py b/tests/unit/gapic/aiplatform_v1/test_tensorboard_service.py new file mode 100644 index 0000000000..0a5b116fe3 --- /dev/null +++ b/tests/unit/gapic/aiplatform_v1/test_tensorboard_service.py @@ -0,0 +1,9202 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule + + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.aiplatform_v1.services.tensorboard_service import ( + TensorboardServiceAsyncClient, +) +from google.cloud.aiplatform_v1.services.tensorboard_service import ( + TensorboardServiceClient, +) +from google.cloud.aiplatform_v1.services.tensorboard_service import pagers +from google.cloud.aiplatform_v1.services.tensorboard_service import transports +from google.cloud.aiplatform_v1.types import encryption_spec +from google.cloud.aiplatform_v1.types import operation as gca_operation +from google.cloud.aiplatform_v1.types import tensorboard +from google.cloud.aiplatform_v1.types import tensorboard as gca_tensorboard +from google.cloud.aiplatform_v1.types import tensorboard_data +from google.cloud.aiplatform_v1.types import tensorboard_experiment +from google.cloud.aiplatform_v1.types import ( + tensorboard_experiment as gca_tensorboard_experiment, +) +from google.cloud.aiplatform_v1.types import tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_run as gca_tensorboard_run +from google.cloud.aiplatform_v1.types import tensorboard_service +from google.cloud.aiplatform_v1.types import tensorboard_time_series +from google.cloud.aiplatform_v1.types import ( + tensorboard_time_series as gca_tensorboard_time_series, +) +from google.longrunning import operations_pb2 +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert TensorboardServiceClient._get_default_mtls_endpoint(None) is None + assert ( + TensorboardServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + TensorboardServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + TensorboardServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + TensorboardServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + TensorboardServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +@pytest.mark.parametrize( + "client_class", [TensorboardServiceClient, TensorboardServiceAsyncClient,] +) +def test_tensorboard_service_client_from_service_account_info(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "aiplatform.googleapis.com:443" + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.TensorboardServiceGrpcTransport, "grpc"), + (transports.TensorboardServiceGrpcAsyncIOTransport, "grpc_asyncio"), + ], +) +def test_tensorboard_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", [TensorboardServiceClient, TensorboardServiceAsyncClient,] +) +def test_tensorboard_service_client_from_service_account_file(client_class): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "aiplatform.googleapis.com:443" + + +def test_tensorboard_service_client_get_transport_class(): + transport = TensorboardServiceClient.get_transport_class() + available_transports = [ + transports.TensorboardServiceGrpcTransport, + ] + assert transport in available_transports + + transport = TensorboardServiceClient.get_transport_class("grpc") + assert transport == transports.TensorboardServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (TensorboardServiceClient, transports.TensorboardServiceGrpcTransport, "grpc"), + ( + TensorboardServiceAsyncClient, + transports.TensorboardServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +@mock.patch.object( + TensorboardServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(TensorboardServiceClient), +) +@mock.patch.object( + TensorboardServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(TensorboardServiceAsyncClient), +) +def test_tensorboard_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(TensorboardServiceClient, "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(TensorboardServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class() + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError): + client = client_class() + + # 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(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + TensorboardServiceClient, + transports.TensorboardServiceGrpcTransport, + "grpc", + "true", + ), + ( + TensorboardServiceAsyncClient, + transports.TensorboardServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + TensorboardServiceClient, + transports.TensorboardServiceGrpcTransport, + "grpc", + "false", + ), + ( + TensorboardServiceAsyncClient, + transports.TensorboardServiceGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ], +) +@mock.patch.object( + TensorboardServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(TensorboardServiceClient), +) +@mock.patch.object( + TensorboardServiceAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(TensorboardServiceAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_tensorboard_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(transport=transport_name, client_options=options) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (TensorboardServiceClient, transports.TensorboardServiceGrpcTransport, "grpc"), + ( + TensorboardServiceAsyncClient, + transports.TensorboardServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_tensorboard_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(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (TensorboardServiceClient, transports.TensorboardServiceGrpcTransport, "grpc"), + ( + TensorboardServiceAsyncClient, + transports.TensorboardServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_tensorboard_service_client_client_options_credentials_file( + client_class, transport_class, transport_name +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + +def test_tensorboard_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.aiplatform_v1.services.tensorboard_service.transports.TensorboardServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = TensorboardServiceClient( + 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, + ) + + +def test_create_tensorboard( + transport: str = "grpc", request_type=tensorboard_service.CreateTensorboardRequest +): + client = TensorboardServiceClient( + 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_tensorboard), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_tensorboard(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_tensorboard_from_dict(): + test_create_tensorboard(request_type=dict) + + +def test_create_tensorboard_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard), "__call__" + ) as call: + client.create_tensorboard() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardRequest() + + +@pytest.mark.asyncio +async def test_create_tensorboard_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.CreateTensorboardRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard), "__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_tensorboard(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_tensorboard_async_from_dict(): + await test_create_tensorboard_async(request_type=dict) + + +def test_create_tensorboard_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.CreateTensorboardRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_tensorboard(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_tensorboard_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.CreateTensorboardRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.create_tensorboard(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_tensorboard_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard), "__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_tensorboard( + parent="parent_value", + tensorboard=gca_tensorboard.Tensorboard(name="name_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard + mock_val = gca_tensorboard.Tensorboard(name="name_value") + assert arg == mock_val + + +def test_create_tensorboard_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard( + tensorboard_service.CreateTensorboardRequest(), + parent="parent_value", + tensorboard=gca_tensorboard.Tensorboard(name="name_value"), + ) + + +@pytest.mark.asyncio +async def test_create_tensorboard_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard), "__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_tensorboard( + parent="parent_value", + tensorboard=gca_tensorboard.Tensorboard(name="name_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard + mock_val = gca_tensorboard.Tensorboard(name="name_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_tensorboard_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_tensorboard( + tensorboard_service.CreateTensorboardRequest(), + parent="parent_value", + tensorboard=gca_tensorboard.Tensorboard(name="name_value"), + ) + + +def test_get_tensorboard( + transport: str = "grpc", request_type=tensorboard_service.GetTensorboardRequest +): + client = TensorboardServiceClient( + 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_tensorboard), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard.Tensorboard( + name="name_value", + display_name="display_name_value", + description="description_value", + blob_storage_path_prefix="blob_storage_path_prefix_value", + run_count=989, + etag="etag_value", + ) + response = client.get_tensorboard(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard.Tensorboard) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.blob_storage_path_prefix == "blob_storage_path_prefix_value" + assert response.run_count == 989 + assert response.etag == "etag_value" + + +def test_get_tensorboard_from_dict(): + test_get_tensorboard(request_type=dict) + + +def test_get_tensorboard_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tensorboard), "__call__") as call: + client.get_tensorboard() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardRequest() + + +@pytest.mark.asyncio +async def test_get_tensorboard_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.GetTensorboardRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard.Tensorboard( + name="name_value", + display_name="display_name_value", + description="description_value", + blob_storage_path_prefix="blob_storage_path_prefix_value", + run_count=989, + etag="etag_value", + ) + ) + response = await client.get_tensorboard(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard.Tensorboard) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.blob_storage_path_prefix == "blob_storage_path_prefix_value" + assert response.run_count == 989 + assert response.etag == "etag_value" + + +@pytest.mark.asyncio +async def test_get_tensorboard_async_from_dict(): + await test_get_tensorboard_async(request_type=dict) + + +def test_get_tensorboard_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.GetTensorboardRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tensorboard), "__call__") as call: + call.return_value = tensorboard.Tensorboard() + client.get_tensorboard(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_tensorboard_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.GetTensorboardRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tensorboard), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard.Tensorboard() + ) + await client.get_tensorboard(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_tensorboard_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tensorboard), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard.Tensorboard() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_tensorboard(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_tensorboard_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard( + tensorboard_service.GetTensorboardRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_tensorboard_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tensorboard), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard.Tensorboard() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard.Tensorboard() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_tensorboard(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_tensorboard_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_tensorboard( + tensorboard_service.GetTensorboardRequest(), name="name_value", + ) + + +def test_update_tensorboard( + transport: str = "grpc", request_type=tensorboard_service.UpdateTensorboardRequest +): + client = TensorboardServiceClient( + 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_tensorboard), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.update_tensorboard(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_update_tensorboard_from_dict(): + test_update_tensorboard(request_type=dict) + + +def test_update_tensorboard_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard), "__call__" + ) as call: + client.update_tensorboard() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardRequest() + + +@pytest.mark.asyncio +async def test_update_tensorboard_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.UpdateTensorboardRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard), "__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_tensorboard(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_update_tensorboard_async_from_dict(): + await test_update_tensorboard_async(request_type=dict) + + +def test_update_tensorboard_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.UpdateTensorboardRequest() + + request.tensorboard.name = "tensorboard.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.update_tensorboard(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", "tensorboard.name=tensorboard.name/value",) in kw[ + "metadata" + ] + + +@pytest.mark.asyncio +async def test_update_tensorboard_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.UpdateTensorboardRequest() + + request.tensorboard.name = "tensorboard.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.update_tensorboard(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", "tensorboard.name=tensorboard.name/value",) in kw[ + "metadata" + ] + + +def test_update_tensorboard_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard), "__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_tensorboard( + tensorboard=gca_tensorboard.Tensorboard(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].tensorboard + mock_val = gca_tensorboard.Tensorboard(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_tensorboard_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard( + tensorboard_service.UpdateTensorboardRequest(), + tensorboard=gca_tensorboard.Tensorboard(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_tensorboard_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard), "__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_tensorboard( + tensorboard=gca_tensorboard.Tensorboard(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].tensorboard + mock_val = gca_tensorboard.Tensorboard(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_tensorboard_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_tensorboard( + tensorboard_service.UpdateTensorboardRequest(), + tensorboard=gca_tensorboard.Tensorboard(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_list_tensorboards( + transport: str = "grpc", request_type=tensorboard_service.ListTensorboardsRequest +): + client = TensorboardServiceClient( + 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_tensorboards), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_tensorboards(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTensorboardsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_tensorboards_from_dict(): + test_list_tensorboards(request_type=dict) + + +def test_list_tensorboards_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboards), "__call__" + ) as call: + client.list_tensorboards() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardsRequest() + + +@pytest.mark.asyncio +async def test_list_tensorboards_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.ListTensorboardsRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboards), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_tensorboards(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTensorboardsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_tensorboards_async_from_dict(): + await test_list_tensorboards_async(request_type=dict) + + +def test_list_tensorboards_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.ListTensorboardsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboards), "__call__" + ) as call: + call.return_value = tensorboard_service.ListTensorboardsResponse() + client.list_tensorboards(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_tensorboards_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.ListTensorboardsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboards), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardsResponse() + ) + await client.list_tensorboards(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_tensorboards_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboards), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_tensorboards(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_tensorboards_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboards( + tensorboard_service.ListTensorboardsRequest(), parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_tensorboards_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboards), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_tensorboards(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_tensorboards_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_tensorboards( + tensorboard_service.ListTensorboardsRequest(), parent="parent_value", + ) + + +def test_list_tensorboards_pager(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboards), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardsResponse( + tensorboards=[ + tensorboard.Tensorboard(), + tensorboard.Tensorboard(), + tensorboard.Tensorboard(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[tensorboard.Tensorboard(),], next_page_token="ghi", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[tensorboard.Tensorboard(), tensorboard.Tensorboard(),], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_tensorboards(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, tensorboard.Tensorboard) for i in results) + + +def test_list_tensorboards_pages(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboards), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardsResponse( + tensorboards=[ + tensorboard.Tensorboard(), + tensorboard.Tensorboard(), + tensorboard.Tensorboard(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[tensorboard.Tensorboard(),], next_page_token="ghi", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[tensorboard.Tensorboard(), tensorboard.Tensorboard(),], + ), + RuntimeError, + ) + pages = list(client.list_tensorboards(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_tensorboards_async_pager(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboards), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardsResponse( + tensorboards=[ + tensorboard.Tensorboard(), + tensorboard.Tensorboard(), + tensorboard.Tensorboard(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[tensorboard.Tensorboard(),], next_page_token="ghi", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[tensorboard.Tensorboard(), tensorboard.Tensorboard(),], + ), + RuntimeError, + ) + async_pager = await client.list_tensorboards(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, tensorboard.Tensorboard) for i in responses) + + +@pytest.mark.asyncio +async def test_list_tensorboards_async_pages(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboards), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardsResponse( + tensorboards=[ + tensorboard.Tensorboard(), + tensorboard.Tensorboard(), + tensorboard.Tensorboard(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[tensorboard.Tensorboard(),], next_page_token="ghi", + ), + tensorboard_service.ListTensorboardsResponse( + tensorboards=[tensorboard.Tensorboard(), tensorboard.Tensorboard(),], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_tensorboards(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_tensorboard( + transport: str = "grpc", request_type=tensorboard_service.DeleteTensorboardRequest +): + client = TensorboardServiceClient( + 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_tensorboard), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_tensorboard(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_tensorboard_from_dict(): + test_delete_tensorboard(request_type=dict) + + +def test_delete_tensorboard_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard), "__call__" + ) as call: + client.delete_tensorboard() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardRequest() + + +@pytest.mark.asyncio +async def test_delete_tensorboard_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.DeleteTensorboardRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard), "__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_tensorboard(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_delete_tensorboard_async_from_dict(): + await test_delete_tensorboard_async(request_type=dict) + + +def test_delete_tensorboard_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.DeleteTensorboardRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_tensorboard(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_tensorboard_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.DeleteTensorboardRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_tensorboard(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_tensorboard_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard), "__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_tensorboard(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_tensorboard_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard( + tensorboard_service.DeleteTensorboardRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_tensorboard_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard), "__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_tensorboard(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_tensorboard_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_tensorboard( + tensorboard_service.DeleteTensorboardRequest(), name="name_value", + ) + + +def test_create_tensorboard_experiment( + transport: str = "grpc", + request_type=tensorboard_service.CreateTensorboardExperimentRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_experiment.TensorboardExperiment( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + source="source_value", + ) + response = client.create_tensorboard_experiment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardExperimentRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_experiment.TensorboardExperiment) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + assert response.source == "source_value" + + +def test_create_tensorboard_experiment_from_dict(): + test_create_tensorboard_experiment(request_type=dict) + + +def test_create_tensorboard_experiment_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_experiment), "__call__" + ) as call: + client.create_tensorboard_experiment() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardExperimentRequest() + + +@pytest.mark.asyncio +async def test_create_tensorboard_experiment_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.CreateTensorboardExperimentRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_experiment.TensorboardExperiment( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + source="source_value", + ) + ) + response = await client.create_tensorboard_experiment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardExperimentRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_experiment.TensorboardExperiment) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + assert response.source == "source_value" + + +@pytest.mark.asyncio +async def test_create_tensorboard_experiment_async_from_dict(): + await test_create_tensorboard_experiment_async(request_type=dict) + + +def test_create_tensorboard_experiment_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.CreateTensorboardExperimentRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_experiment), "__call__" + ) as call: + call.return_value = gca_tensorboard_experiment.TensorboardExperiment() + client.create_tensorboard_experiment(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_tensorboard_experiment_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.CreateTensorboardExperimentRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_experiment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_experiment.TensorboardExperiment() + ) + await client.create_tensorboard_experiment(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_tensorboard_experiment_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_experiment.TensorboardExperiment() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_tensorboard_experiment( + parent="parent_value", + tensorboard_experiment=gca_tensorboard_experiment.TensorboardExperiment( + name="name_value" + ), + tensorboard_experiment_id="tensorboard_experiment_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].tensorboard_experiment + mock_val = gca_tensorboard_experiment.TensorboardExperiment(name="name_value") + assert arg == mock_val + arg = args[0].tensorboard_experiment_id + mock_val = "tensorboard_experiment_id_value" + assert arg == mock_val + + +def test_create_tensorboard_experiment_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_experiment( + tensorboard_service.CreateTensorboardExperimentRequest(), + parent="parent_value", + tensorboard_experiment=gca_tensorboard_experiment.TensorboardExperiment( + name="name_value" + ), + tensorboard_experiment_id="tensorboard_experiment_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_tensorboard_experiment_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_experiment.TensorboardExperiment() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_experiment.TensorboardExperiment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_tensorboard_experiment( + parent="parent_value", + tensorboard_experiment=gca_tensorboard_experiment.TensorboardExperiment( + name="name_value" + ), + tensorboard_experiment_id="tensorboard_experiment_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].tensorboard_experiment + mock_val = gca_tensorboard_experiment.TensorboardExperiment(name="name_value") + assert arg == mock_val + arg = args[0].tensorboard_experiment_id + mock_val = "tensorboard_experiment_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_tensorboard_experiment_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_tensorboard_experiment( + tensorboard_service.CreateTensorboardExperimentRequest(), + parent="parent_value", + tensorboard_experiment=gca_tensorboard_experiment.TensorboardExperiment( + name="name_value" + ), + tensorboard_experiment_id="tensorboard_experiment_id_value", + ) + + +def test_get_tensorboard_experiment( + transport: str = "grpc", + request_type=tensorboard_service.GetTensorboardExperimentRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_experiment.TensorboardExperiment( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + source="source_value", + ) + response = client.get_tensorboard_experiment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardExperimentRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_experiment.TensorboardExperiment) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + assert response.source == "source_value" + + +def test_get_tensorboard_experiment_from_dict(): + test_get_tensorboard_experiment(request_type=dict) + + +def test_get_tensorboard_experiment_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_experiment), "__call__" + ) as call: + client.get_tensorboard_experiment() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardExperimentRequest() + + +@pytest.mark.asyncio +async def test_get_tensorboard_experiment_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.GetTensorboardExperimentRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_experiment.TensorboardExperiment( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + source="source_value", + ) + ) + response = await client.get_tensorboard_experiment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardExperimentRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_experiment.TensorboardExperiment) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + assert response.source == "source_value" + + +@pytest.mark.asyncio +async def test_get_tensorboard_experiment_async_from_dict(): + await test_get_tensorboard_experiment_async(request_type=dict) + + +def test_get_tensorboard_experiment_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.GetTensorboardExperimentRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_experiment), "__call__" + ) as call: + call.return_value = tensorboard_experiment.TensorboardExperiment() + client.get_tensorboard_experiment(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_tensorboard_experiment_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.GetTensorboardExperimentRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_experiment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_experiment.TensorboardExperiment() + ) + await client.get_tensorboard_experiment(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_tensorboard_experiment_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_experiment.TensorboardExperiment() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_tensorboard_experiment(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_tensorboard_experiment_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_experiment( + tensorboard_service.GetTensorboardExperimentRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_tensorboard_experiment_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_experiment.TensorboardExperiment() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_experiment.TensorboardExperiment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_tensorboard_experiment(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_tensorboard_experiment_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_tensorboard_experiment( + tensorboard_service.GetTensorboardExperimentRequest(), name="name_value", + ) + + +def test_update_tensorboard_experiment( + transport: str = "grpc", + request_type=tensorboard_service.UpdateTensorboardExperimentRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_experiment.TensorboardExperiment( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + source="source_value", + ) + response = client.update_tensorboard_experiment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardExperimentRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_experiment.TensorboardExperiment) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + assert response.source == "source_value" + + +def test_update_tensorboard_experiment_from_dict(): + test_update_tensorboard_experiment(request_type=dict) + + +def test_update_tensorboard_experiment_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_experiment), "__call__" + ) as call: + client.update_tensorboard_experiment() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardExperimentRequest() + + +@pytest.mark.asyncio +async def test_update_tensorboard_experiment_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.UpdateTensorboardExperimentRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_experiment.TensorboardExperiment( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + source="source_value", + ) + ) + response = await client.update_tensorboard_experiment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardExperimentRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_experiment.TensorboardExperiment) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + assert response.source == "source_value" + + +@pytest.mark.asyncio +async def test_update_tensorboard_experiment_async_from_dict(): + await test_update_tensorboard_experiment_async(request_type=dict) + + +def test_update_tensorboard_experiment_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.UpdateTensorboardExperimentRequest() + + request.tensorboard_experiment.name = "tensorboard_experiment.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_experiment), "__call__" + ) as call: + call.return_value = gca_tensorboard_experiment.TensorboardExperiment() + client.update_tensorboard_experiment(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", + "tensorboard_experiment.name=tensorboard_experiment.name/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_tensorboard_experiment_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.UpdateTensorboardExperimentRequest() + + request.tensorboard_experiment.name = "tensorboard_experiment.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_experiment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_experiment.TensorboardExperiment() + ) + await client.update_tensorboard_experiment(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", + "tensorboard_experiment.name=tensorboard_experiment.name/value", + ) in kw["metadata"] + + +def test_update_tensorboard_experiment_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_experiment.TensorboardExperiment() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_tensorboard_experiment( + tensorboard_experiment=gca_tensorboard_experiment.TensorboardExperiment( + 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].tensorboard_experiment + mock_val = gca_tensorboard_experiment.TensorboardExperiment(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_tensorboard_experiment_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_experiment( + tensorboard_service.UpdateTensorboardExperimentRequest(), + tensorboard_experiment=gca_tensorboard_experiment.TensorboardExperiment( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_tensorboard_experiment_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_experiment.TensorboardExperiment() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_experiment.TensorboardExperiment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_tensorboard_experiment( + tensorboard_experiment=gca_tensorboard_experiment.TensorboardExperiment( + 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].tensorboard_experiment + mock_val = gca_tensorboard_experiment.TensorboardExperiment(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_tensorboard_experiment_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_tensorboard_experiment( + tensorboard_service.UpdateTensorboardExperimentRequest(), + tensorboard_experiment=gca_tensorboard_experiment.TensorboardExperiment( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_list_tensorboard_experiments( + transport: str = "grpc", + request_type=tensorboard_service.ListTensorboardExperimentsRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_experiments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardExperimentsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_tensorboard_experiments(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardExperimentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTensorboardExperimentsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_tensorboard_experiments_from_dict(): + test_list_tensorboard_experiments(request_type=dict) + + +def test_list_tensorboard_experiments_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_experiments), "__call__" + ) as call: + client.list_tensorboard_experiments() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardExperimentsRequest() + + +@pytest.mark.asyncio +async def test_list_tensorboard_experiments_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.ListTensorboardExperimentsRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_experiments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardExperimentsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_tensorboard_experiments(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardExperimentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTensorboardExperimentsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_tensorboard_experiments_async_from_dict(): + await test_list_tensorboard_experiments_async(request_type=dict) + + +def test_list_tensorboard_experiments_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.ListTensorboardExperimentsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_experiments), "__call__" + ) as call: + call.return_value = tensorboard_service.ListTensorboardExperimentsResponse() + client.list_tensorboard_experiments(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_tensorboard_experiments_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.ListTensorboardExperimentsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_experiments), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardExperimentsResponse() + ) + await client.list_tensorboard_experiments(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_tensorboard_experiments_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_experiments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardExperimentsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_tensorboard_experiments(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_tensorboard_experiments_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_experiments( + tensorboard_service.ListTensorboardExperimentsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_tensorboard_experiments_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_experiments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardExperimentsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardExperimentsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_tensorboard_experiments(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_tensorboard_experiments_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_tensorboard_experiments( + tensorboard_service.ListTensorboardExperimentsRequest(), + parent="parent_value", + ) + + +def test_list_tensorboard_experiments_pager(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_experiments), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + ], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_tensorboard_experiments(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all( + isinstance(i, tensorboard_experiment.TensorboardExperiment) for i in results + ) + + +def test_list_tensorboard_experiments_pages(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_experiments), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + ], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + ], + ), + RuntimeError, + ) + pages = list(client.list_tensorboard_experiments(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_tensorboard_experiments_async_pager(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_experiments), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + ], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_tensorboard_experiments(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, tensorboard_experiment.TensorboardExperiment) + for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_tensorboard_experiments_async_pages(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_experiments), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + ], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardExperimentsResponse( + tensorboard_experiments=[ + tensorboard_experiment.TensorboardExperiment(), + tensorboard_experiment.TensorboardExperiment(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in ( + await client.list_tensorboard_experiments(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_tensorboard_experiment( + transport: str = "grpc", + request_type=tensorboard_service.DeleteTensorboardExperimentRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_experiment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_tensorboard_experiment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardExperimentRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_tensorboard_experiment_from_dict(): + test_delete_tensorboard_experiment(request_type=dict) + + +def test_delete_tensorboard_experiment_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_experiment), "__call__" + ) as call: + client.delete_tensorboard_experiment() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardExperimentRequest() + + +@pytest.mark.asyncio +async def test_delete_tensorboard_experiment_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.DeleteTensorboardExperimentRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_experiment), "__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_tensorboard_experiment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardExperimentRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_delete_tensorboard_experiment_async_from_dict(): + await test_delete_tensorboard_experiment_async(request_type=dict) + + +def test_delete_tensorboard_experiment_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.DeleteTensorboardExperimentRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_experiment), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_tensorboard_experiment(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_tensorboard_experiment_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.DeleteTensorboardExperimentRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_experiment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_tensorboard_experiment(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_tensorboard_experiment_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_experiment), "__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_tensorboard_experiment(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_tensorboard_experiment_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_experiment( + tensorboard_service.DeleteTensorboardExperimentRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_tensorboard_experiment_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_experiment), "__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_tensorboard_experiment(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_tensorboard_experiment_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_tensorboard_experiment( + tensorboard_service.DeleteTensorboardExperimentRequest(), name="name_value", + ) + + +def test_create_tensorboard_run( + transport: str = "grpc", + request_type=tensorboard_service.CreateTensorboardRunRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_run.TensorboardRun( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + ) + response = client.create_tensorboard_run(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardRunRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_run.TensorboardRun) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + + +def test_create_tensorboard_run_from_dict(): + test_create_tensorboard_run(request_type=dict) + + +def test_create_tensorboard_run_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_run), "__call__" + ) as call: + client.create_tensorboard_run() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardRunRequest() + + +@pytest.mark.asyncio +async def test_create_tensorboard_run_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.CreateTensorboardRunRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_run.TensorboardRun( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + ) + ) + response = await client.create_tensorboard_run(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardRunRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_run.TensorboardRun) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + + +@pytest.mark.asyncio +async def test_create_tensorboard_run_async_from_dict(): + await test_create_tensorboard_run_async(request_type=dict) + + +def test_create_tensorboard_run_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.CreateTensorboardRunRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_run), "__call__" + ) as call: + call.return_value = gca_tensorboard_run.TensorboardRun() + client.create_tensorboard_run(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_tensorboard_run_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.CreateTensorboardRunRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_run), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_run.TensorboardRun() + ) + await client.create_tensorboard_run(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_tensorboard_run_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_run.TensorboardRun() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_tensorboard_run( + parent="parent_value", + tensorboard_run=gca_tensorboard_run.TensorboardRun(name="name_value"), + tensorboard_run_id="tensorboard_run_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].tensorboard_run + mock_val = gca_tensorboard_run.TensorboardRun(name="name_value") + assert arg == mock_val + arg = args[0].tensorboard_run_id + mock_val = "tensorboard_run_id_value" + assert arg == mock_val + + +def test_create_tensorboard_run_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_run( + tensorboard_service.CreateTensorboardRunRequest(), + parent="parent_value", + tensorboard_run=gca_tensorboard_run.TensorboardRun(name="name_value"), + tensorboard_run_id="tensorboard_run_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_tensorboard_run_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_run.TensorboardRun() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_run.TensorboardRun() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_tensorboard_run( + parent="parent_value", + tensorboard_run=gca_tensorboard_run.TensorboardRun(name="name_value"), + tensorboard_run_id="tensorboard_run_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].tensorboard_run + mock_val = gca_tensorboard_run.TensorboardRun(name="name_value") + assert arg == mock_val + arg = args[0].tensorboard_run_id + mock_val = "tensorboard_run_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_tensorboard_run_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_tensorboard_run( + tensorboard_service.CreateTensorboardRunRequest(), + parent="parent_value", + tensorboard_run=gca_tensorboard_run.TensorboardRun(name="name_value"), + tensorboard_run_id="tensorboard_run_id_value", + ) + + +def test_batch_create_tensorboard_runs( + transport: str = "grpc", + request_type=tensorboard_service.BatchCreateTensorboardRunsRequest, +): + client = TensorboardServiceClient( + 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_create_tensorboard_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.BatchCreateTensorboardRunsResponse() + response = client.batch_create_tensorboard_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] == tensorboard_service.BatchCreateTensorboardRunsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_service.BatchCreateTensorboardRunsResponse) + + +def test_batch_create_tensorboard_runs_from_dict(): + test_batch_create_tensorboard_runs(request_type=dict) + + +def test_batch_create_tensorboard_runs_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_runs), "__call__" + ) as call: + client.batch_create_tensorboard_runs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.BatchCreateTensorboardRunsRequest() + + +@pytest.mark.asyncio +async def test_batch_create_tensorboard_runs_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.BatchCreateTensorboardRunsRequest, +): + client = TensorboardServiceAsyncClient( + 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_create_tensorboard_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.BatchCreateTensorboardRunsResponse() + ) + response = await client.batch_create_tensorboard_runs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.BatchCreateTensorboardRunsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_service.BatchCreateTensorboardRunsResponse) + + +@pytest.mark.asyncio +async def test_batch_create_tensorboard_runs_async_from_dict(): + await test_batch_create_tensorboard_runs_async(request_type=dict) + + +def test_batch_create_tensorboard_runs_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.BatchCreateTensorboardRunsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_runs), "__call__" + ) as call: + call.return_value = tensorboard_service.BatchCreateTensorboardRunsResponse() + client.batch_create_tensorboard_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_batch_create_tensorboard_runs_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.BatchCreateTensorboardRunsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_runs), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.BatchCreateTensorboardRunsResponse() + ) + await client.batch_create_tensorboard_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_batch_create_tensorboard_runs_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.BatchCreateTensorboardRunsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_create_tensorboard_runs( + parent="parent_value", + requests=[ + tensorboard_service.CreateTensorboardRunRequest(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 + arg = args[0].requests + mock_val = [ + tensorboard_service.CreateTensorboardRunRequest(parent="parent_value") + ] + assert arg == mock_val + + +def test_batch_create_tensorboard_runs_flattened_error(): + client = TensorboardServiceClient( + 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.batch_create_tensorboard_runs( + tensorboard_service.BatchCreateTensorboardRunsRequest(), + parent="parent_value", + requests=[ + tensorboard_service.CreateTensorboardRunRequest(parent="parent_value") + ], + ) + + +@pytest.mark.asyncio +async def test_batch_create_tensorboard_runs_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.BatchCreateTensorboardRunsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.BatchCreateTensorboardRunsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_create_tensorboard_runs( + parent="parent_value", + requests=[ + tensorboard_service.CreateTensorboardRunRequest(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 + arg = args[0].requests + mock_val = [ + tensorboard_service.CreateTensorboardRunRequest(parent="parent_value") + ] + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_batch_create_tensorboard_runs_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_create_tensorboard_runs( + tensorboard_service.BatchCreateTensorboardRunsRequest(), + parent="parent_value", + requests=[ + tensorboard_service.CreateTensorboardRunRequest(parent="parent_value") + ], + ) + + +def test_get_tensorboard_run( + transport: str = "grpc", request_type=tensorboard_service.GetTensorboardRunRequest +): + client = TensorboardServiceClient( + 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_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_run.TensorboardRun( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + ) + response = client.get_tensorboard_run(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardRunRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_run.TensorboardRun) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + + +def test_get_tensorboard_run_from_dict(): + test_get_tensorboard_run(request_type=dict) + + +def test_get_tensorboard_run_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_run), "__call__" + ) as call: + client.get_tensorboard_run() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardRunRequest() + + +@pytest.mark.asyncio +async def test_get_tensorboard_run_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.GetTensorboardRunRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_run.TensorboardRun( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + ) + ) + response = await client.get_tensorboard_run(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardRunRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_run.TensorboardRun) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + + +@pytest.mark.asyncio +async def test_get_tensorboard_run_async_from_dict(): + await test_get_tensorboard_run_async(request_type=dict) + + +def test_get_tensorboard_run_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.GetTensorboardRunRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_run), "__call__" + ) as call: + call.return_value = tensorboard_run.TensorboardRun() + client.get_tensorboard_run(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_tensorboard_run_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.GetTensorboardRunRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_run), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_run.TensorboardRun() + ) + await client.get_tensorboard_run(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_tensorboard_run_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_run.TensorboardRun() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_tensorboard_run(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_tensorboard_run_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_run( + tensorboard_service.GetTensorboardRunRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_tensorboard_run_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_run.TensorboardRun() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_run.TensorboardRun() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_tensorboard_run(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_tensorboard_run_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_tensorboard_run( + tensorboard_service.GetTensorboardRunRequest(), name="name_value", + ) + + +def test_update_tensorboard_run( + transport: str = "grpc", + request_type=tensorboard_service.UpdateTensorboardRunRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_run.TensorboardRun( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + ) + response = client.update_tensorboard_run(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardRunRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_run.TensorboardRun) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + + +def test_update_tensorboard_run_from_dict(): + test_update_tensorboard_run(request_type=dict) + + +def test_update_tensorboard_run_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_run), "__call__" + ) as call: + client.update_tensorboard_run() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardRunRequest() + + +@pytest.mark.asyncio +async def test_update_tensorboard_run_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.UpdateTensorboardRunRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_run.TensorboardRun( + name="name_value", + display_name="display_name_value", + description="description_value", + etag="etag_value", + ) + ) + response = await client.update_tensorboard_run(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardRunRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_run.TensorboardRun) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.etag == "etag_value" + + +@pytest.mark.asyncio +async def test_update_tensorboard_run_async_from_dict(): + await test_update_tensorboard_run_async(request_type=dict) + + +def test_update_tensorboard_run_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.UpdateTensorboardRunRequest() + + request.tensorboard_run.name = "tensorboard_run.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_run), "__call__" + ) as call: + call.return_value = gca_tensorboard_run.TensorboardRun() + client.update_tensorboard_run(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", + "tensorboard_run.name=tensorboard_run.name/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_tensorboard_run_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.UpdateTensorboardRunRequest() + + request.tensorboard_run.name = "tensorboard_run.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_run), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_run.TensorboardRun() + ) + await client.update_tensorboard_run(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", + "tensorboard_run.name=tensorboard_run.name/value", + ) in kw["metadata"] + + +def test_update_tensorboard_run_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_run.TensorboardRun() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_tensorboard_run( + tensorboard_run=gca_tensorboard_run.TensorboardRun(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].tensorboard_run + mock_val = gca_tensorboard_run.TensorboardRun(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_tensorboard_run_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_run( + tensorboard_service.UpdateTensorboardRunRequest(), + tensorboard_run=gca_tensorboard_run.TensorboardRun(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_tensorboard_run_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_run.TensorboardRun() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_run.TensorboardRun() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_tensorboard_run( + tensorboard_run=gca_tensorboard_run.TensorboardRun(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].tensorboard_run + mock_val = gca_tensorboard_run.TensorboardRun(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_tensorboard_run_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_tensorboard_run( + tensorboard_service.UpdateTensorboardRunRequest(), + tensorboard_run=gca_tensorboard_run.TensorboardRun(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_list_tensorboard_runs( + transport: str = "grpc", request_type=tensorboard_service.ListTensorboardRunsRequest +): + client = TensorboardServiceClient( + 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_tensorboard_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardRunsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_tensorboard_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] == tensorboard_service.ListTensorboardRunsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTensorboardRunsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_tensorboard_runs_from_dict(): + test_list_tensorboard_runs(request_type=dict) + + +def test_list_tensorboard_runs_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_runs), "__call__" + ) as call: + client.list_tensorboard_runs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardRunsRequest() + + +@pytest.mark.asyncio +async def test_list_tensorboard_runs_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.ListTensorboardRunsRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardRunsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_tensorboard_runs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardRunsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTensorboardRunsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_tensorboard_runs_async_from_dict(): + await test_list_tensorboard_runs_async(request_type=dict) + + +def test_list_tensorboard_runs_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.ListTensorboardRunsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_runs), "__call__" + ) as call: + call.return_value = tensorboard_service.ListTensorboardRunsResponse() + client.list_tensorboard_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_list_tensorboard_runs_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.ListTensorboardRunsRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_runs), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardRunsResponse() + ) + await client.list_tensorboard_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_list_tensorboard_runs_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardRunsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_tensorboard_runs(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_tensorboard_runs_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_runs( + tensorboard_service.ListTensorboardRunsRequest(), parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_tensorboard_runs_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_runs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardRunsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardRunsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_tensorboard_runs(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_tensorboard_runs_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_tensorboard_runs( + tensorboard_service.ListTensorboardRunsRequest(), parent="parent_value", + ) + + +def test_list_tensorboard_runs_pager(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_runs), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[ + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[tensorboard_run.TensorboardRun(),], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[ + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_tensorboard_runs(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, tensorboard_run.TensorboardRun) for i in results) + + +def test_list_tensorboard_runs_pages(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_runs), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[ + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[tensorboard_run.TensorboardRun(),], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[ + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + ], + ), + RuntimeError, + ) + pages = list(client.list_tensorboard_runs(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_tensorboard_runs_async_pager(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_runs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[ + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[tensorboard_run.TensorboardRun(),], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[ + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_tensorboard_runs(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, tensorboard_run.TensorboardRun) for i in responses) + + +@pytest.mark.asyncio +async def test_list_tensorboard_runs_async_pages(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_runs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[ + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[tensorboard_run.TensorboardRun(),], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardRunsResponse( + tensorboard_runs=[ + tensorboard_run.TensorboardRun(), + tensorboard_run.TensorboardRun(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in (await client.list_tensorboard_runs(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_tensorboard_run( + transport: str = "grpc", + request_type=tensorboard_service.DeleteTensorboardRunRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_run), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_tensorboard_run(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardRunRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_tensorboard_run_from_dict(): + test_delete_tensorboard_run(request_type=dict) + + +def test_delete_tensorboard_run_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_run), "__call__" + ) as call: + client.delete_tensorboard_run() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardRunRequest() + + +@pytest.mark.asyncio +async def test_delete_tensorboard_run_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.DeleteTensorboardRunRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_run), "__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_tensorboard_run(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardRunRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_delete_tensorboard_run_async_from_dict(): + await test_delete_tensorboard_run_async(request_type=dict) + + +def test_delete_tensorboard_run_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.DeleteTensorboardRunRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_run), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_tensorboard_run(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_tensorboard_run_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.DeleteTensorboardRunRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_run), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_tensorboard_run(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_tensorboard_run_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_run), "__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_tensorboard_run(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_tensorboard_run_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_run( + tensorboard_service.DeleteTensorboardRunRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_tensorboard_run_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_run), "__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_tensorboard_run(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_tensorboard_run_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_tensorboard_run( + tensorboard_service.DeleteTensorboardRunRequest(), name="name_value", + ) + + +def test_batch_create_tensorboard_time_series( + transport: str = "grpc", + request_type=tensorboard_service.BatchCreateTensorboardTimeSeriesRequest, +): + client = TensorboardServiceClient( + 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_create_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + tensorboard_service.BatchCreateTensorboardTimeSeriesResponse() + ) + response = client.batch_create_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.BatchCreateTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance( + response, tensorboard_service.BatchCreateTensorboardTimeSeriesResponse + ) + + +def test_batch_create_tensorboard_time_series_from_dict(): + test_batch_create_tensorboard_time_series(request_type=dict) + + +def test_batch_create_tensorboard_time_series_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_time_series), "__call__" + ) as call: + client.batch_create_tensorboard_time_series() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.BatchCreateTensorboardTimeSeriesRequest() + + +@pytest.mark.asyncio +async def test_batch_create_tensorboard_time_series_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.BatchCreateTensorboardTimeSeriesRequest, +): + client = TensorboardServiceAsyncClient( + 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_create_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.BatchCreateTensorboardTimeSeriesResponse() + ) + response = await client.batch_create_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.BatchCreateTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance( + response, tensorboard_service.BatchCreateTensorboardTimeSeriesResponse + ) + + +@pytest.mark.asyncio +async def test_batch_create_tensorboard_time_series_async_from_dict(): + await test_batch_create_tensorboard_time_series_async(request_type=dict) + + +def test_batch_create_tensorboard_time_series_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.BatchCreateTensorboardTimeSeriesRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_time_series), "__call__" + ) as call: + call.return_value = ( + tensorboard_service.BatchCreateTensorboardTimeSeriesResponse() + ) + client.batch_create_tensorboard_time_series(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_create_tensorboard_time_series_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.BatchCreateTensorboardTimeSeriesRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_time_series), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.BatchCreateTensorboardTimeSeriesResponse() + ) + await client.batch_create_tensorboard_time_series(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_batch_create_tensorboard_time_series_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + tensorboard_service.BatchCreateTensorboardTimeSeriesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_create_tensorboard_time_series( + parent="parent_value", + requests=[ + tensorboard_service.CreateTensorboardTimeSeriesRequest( + 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 + arg = args[0].requests + mock_val = [ + tensorboard_service.CreateTensorboardTimeSeriesRequest( + parent="parent_value" + ) + ] + assert arg == mock_val + + +def test_batch_create_tensorboard_time_series_flattened_error(): + client = TensorboardServiceClient( + 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.batch_create_tensorboard_time_series( + tensorboard_service.BatchCreateTensorboardTimeSeriesRequest(), + parent="parent_value", + requests=[ + tensorboard_service.CreateTensorboardTimeSeriesRequest( + parent="parent_value" + ) + ], + ) + + +@pytest.mark.asyncio +async def test_batch_create_tensorboard_time_series_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + tensorboard_service.BatchCreateTensorboardTimeSeriesResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.BatchCreateTensorboardTimeSeriesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_create_tensorboard_time_series( + parent="parent_value", + requests=[ + tensorboard_service.CreateTensorboardTimeSeriesRequest( + 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 + arg = args[0].requests + mock_val = [ + tensorboard_service.CreateTensorboardTimeSeriesRequest( + parent="parent_value" + ) + ] + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_batch_create_tensorboard_time_series_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_create_tensorboard_time_series( + tensorboard_service.BatchCreateTensorboardTimeSeriesRequest(), + parent="parent_value", + requests=[ + tensorboard_service.CreateTensorboardTimeSeriesRequest( + parent="parent_value" + ) + ], + ) + + +def test_create_tensorboard_time_series( + transport: str = "grpc", + request_type=tensorboard_service.CreateTensorboardTimeSeriesRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value", + display_name="display_name_value", + description="description_value", + value_type=gca_tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR, + etag="etag_value", + plugin_name="plugin_name_value", + plugin_data=b"plugin_data_blob", + ) + response = client.create_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_time_series.TensorboardTimeSeries) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert ( + response.value_type + == gca_tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR + ) + assert response.etag == "etag_value" + assert response.plugin_name == "plugin_name_value" + assert response.plugin_data == b"plugin_data_blob" + + +def test_create_tensorboard_time_series_from_dict(): + test_create_tensorboard_time_series(request_type=dict) + + +def test_create_tensorboard_time_series_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_time_series), "__call__" + ) as call: + client.create_tensorboard_time_series() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardTimeSeriesRequest() + + +@pytest.mark.asyncio +async def test_create_tensorboard_time_series_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.CreateTensorboardTimeSeriesRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value", + display_name="display_name_value", + description="description_value", + value_type=gca_tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR, + etag="etag_value", + plugin_name="plugin_name_value", + plugin_data=b"plugin_data_blob", + ) + ) + response = await client.create_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.CreateTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_time_series.TensorboardTimeSeries) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert ( + response.value_type + == gca_tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR + ) + assert response.etag == "etag_value" + assert response.plugin_name == "plugin_name_value" + assert response.plugin_data == b"plugin_data_blob" + + +@pytest.mark.asyncio +async def test_create_tensorboard_time_series_async_from_dict(): + await test_create_tensorboard_time_series_async(request_type=dict) + + +def test_create_tensorboard_time_series_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.CreateTensorboardTimeSeriesRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_time_series), "__call__" + ) as call: + call.return_value = gca_tensorboard_time_series.TensorboardTimeSeries() + client.create_tensorboard_time_series(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_tensorboard_time_series_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.CreateTensorboardTimeSeriesRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_time_series), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_time_series.TensorboardTimeSeries() + ) + await client.create_tensorboard_time_series(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_tensorboard_time_series_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_time_series.TensorboardTimeSeries() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_tensorboard_time_series( + parent="parent_value", + tensorboard_time_series=gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value" + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard_time_series + mock_val = gca_tensorboard_time_series.TensorboardTimeSeries(name="name_value") + assert arg == mock_val + + +def test_create_tensorboard_time_series_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_time_series( + tensorboard_service.CreateTensorboardTimeSeriesRequest(), + parent="parent_value", + tensorboard_time_series=gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value" + ), + ) + + +@pytest.mark.asyncio +async def test_create_tensorboard_time_series_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_time_series.TensorboardTimeSeries() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_time_series.TensorboardTimeSeries() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_tensorboard_time_series( + parent="parent_value", + tensorboard_time_series=gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value" + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard_time_series + mock_val = gca_tensorboard_time_series.TensorboardTimeSeries(name="name_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_tensorboard_time_series_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_tensorboard_time_series( + tensorboard_service.CreateTensorboardTimeSeriesRequest(), + parent="parent_value", + tensorboard_time_series=gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value" + ), + ) + + +def test_get_tensorboard_time_series( + transport: str = "grpc", + request_type=tensorboard_service.GetTensorboardTimeSeriesRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_time_series.TensorboardTimeSeries( + name="name_value", + display_name="display_name_value", + description="description_value", + value_type=tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR, + etag="etag_value", + plugin_name="plugin_name_value", + plugin_data=b"plugin_data_blob", + ) + response = client.get_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_time_series.TensorboardTimeSeries) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert ( + response.value_type + == tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR + ) + assert response.etag == "etag_value" + assert response.plugin_name == "plugin_name_value" + assert response.plugin_data == b"plugin_data_blob" + + +def test_get_tensorboard_time_series_from_dict(): + test_get_tensorboard_time_series(request_type=dict) + + +def test_get_tensorboard_time_series_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_time_series), "__call__" + ) as call: + client.get_tensorboard_time_series() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardTimeSeriesRequest() + + +@pytest.mark.asyncio +async def test_get_tensorboard_time_series_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.GetTensorboardTimeSeriesRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_time_series.TensorboardTimeSeries( + name="name_value", + display_name="display_name_value", + description="description_value", + value_type=tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR, + etag="etag_value", + plugin_name="plugin_name_value", + plugin_data=b"plugin_data_blob", + ) + ) + response = await client.get_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.GetTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_time_series.TensorboardTimeSeries) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert ( + response.value_type + == tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR + ) + assert response.etag == "etag_value" + assert response.plugin_name == "plugin_name_value" + assert response.plugin_data == b"plugin_data_blob" + + +@pytest.mark.asyncio +async def test_get_tensorboard_time_series_async_from_dict(): + await test_get_tensorboard_time_series_async(request_type=dict) + + +def test_get_tensorboard_time_series_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.GetTensorboardTimeSeriesRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_time_series), "__call__" + ) as call: + call.return_value = tensorboard_time_series.TensorboardTimeSeries() + client.get_tensorboard_time_series(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_tensorboard_time_series_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.GetTensorboardTimeSeriesRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_time_series), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_time_series.TensorboardTimeSeries() + ) + await client.get_tensorboard_time_series(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_tensorboard_time_series_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_time_series.TensorboardTimeSeries() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_tensorboard_time_series(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_tensorboard_time_series_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_time_series( + tensorboard_service.GetTensorboardTimeSeriesRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_tensorboard_time_series_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_time_series.TensorboardTimeSeries() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_time_series.TensorboardTimeSeries() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_tensorboard_time_series(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_tensorboard_time_series_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_tensorboard_time_series( + tensorboard_service.GetTensorboardTimeSeriesRequest(), name="name_value", + ) + + +def test_update_tensorboard_time_series( + transport: str = "grpc", + request_type=tensorboard_service.UpdateTensorboardTimeSeriesRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value", + display_name="display_name_value", + description="description_value", + value_type=gca_tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR, + etag="etag_value", + plugin_name="plugin_name_value", + plugin_data=b"plugin_data_blob", + ) + response = client.update_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_time_series.TensorboardTimeSeries) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert ( + response.value_type + == gca_tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR + ) + assert response.etag == "etag_value" + assert response.plugin_name == "plugin_name_value" + assert response.plugin_data == b"plugin_data_blob" + + +def test_update_tensorboard_time_series_from_dict(): + test_update_tensorboard_time_series(request_type=dict) + + +def test_update_tensorboard_time_series_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_time_series), "__call__" + ) as call: + client.update_tensorboard_time_series() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardTimeSeriesRequest() + + +@pytest.mark.asyncio +async def test_update_tensorboard_time_series_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.UpdateTensorboardTimeSeriesRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value", + display_name="display_name_value", + description="description_value", + value_type=gca_tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR, + etag="etag_value", + plugin_name="plugin_name_value", + plugin_data=b"plugin_data_blob", + ) + ) + response = await client.update_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.UpdateTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gca_tensorboard_time_series.TensorboardTimeSeries) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert ( + response.value_type + == gca_tensorboard_time_series.TensorboardTimeSeries.ValueType.SCALAR + ) + assert response.etag == "etag_value" + assert response.plugin_name == "plugin_name_value" + assert response.plugin_data == b"plugin_data_blob" + + +@pytest.mark.asyncio +async def test_update_tensorboard_time_series_async_from_dict(): + await test_update_tensorboard_time_series_async(request_type=dict) + + +def test_update_tensorboard_time_series_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.UpdateTensorboardTimeSeriesRequest() + + request.tensorboard_time_series.name = "tensorboard_time_series.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_time_series), "__call__" + ) as call: + call.return_value = gca_tensorboard_time_series.TensorboardTimeSeries() + client.update_tensorboard_time_series(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", + "tensorboard_time_series.name=tensorboard_time_series.name/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_tensorboard_time_series_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.UpdateTensorboardTimeSeriesRequest() + + request.tensorboard_time_series.name = "tensorboard_time_series.name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_time_series), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_time_series.TensorboardTimeSeries() + ) + await client.update_tensorboard_time_series(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", + "tensorboard_time_series.name=tensorboard_time_series.name/value", + ) in kw["metadata"] + + +def test_update_tensorboard_time_series_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_time_series.TensorboardTimeSeries() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_tensorboard_time_series( + tensorboard_time_series=gca_tensorboard_time_series.TensorboardTimeSeries( + 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].tensorboard_time_series + mock_val = gca_tensorboard_time_series.TensorboardTimeSeries(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_tensorboard_time_series_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_time_series( + tensorboard_service.UpdateTensorboardTimeSeriesRequest(), + tensorboard_time_series=gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_tensorboard_time_series_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = gca_tensorboard_time_series.TensorboardTimeSeries() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gca_tensorboard_time_series.TensorboardTimeSeries() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_tensorboard_time_series( + tensorboard_time_series=gca_tensorboard_time_series.TensorboardTimeSeries( + 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].tensorboard_time_series + mock_val = gca_tensorboard_time_series.TensorboardTimeSeries(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_tensorboard_time_series_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_tensorboard_time_series( + tensorboard_service.UpdateTensorboardTimeSeriesRequest(), + tensorboard_time_series=gca_tensorboard_time_series.TensorboardTimeSeries( + name="name_value" + ), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_list_tensorboard_time_series( + transport: str = "grpc", + request_type=tensorboard_service.ListTensorboardTimeSeriesRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardTimeSeriesResponse( + next_page_token="next_page_token_value", + ) + response = client.list_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTensorboardTimeSeriesPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_tensorboard_time_series_from_dict(): + test_list_tensorboard_time_series(request_type=dict) + + +def test_list_tensorboard_time_series_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_time_series), "__call__" + ) as call: + client.list_tensorboard_time_series() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardTimeSeriesRequest() + + +@pytest.mark.asyncio +async def test_list_tensorboard_time_series_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.ListTensorboardTimeSeriesRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardTimeSeriesResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ListTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTensorboardTimeSeriesAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_tensorboard_time_series_async_from_dict(): + await test_list_tensorboard_time_series_async(request_type=dict) + + +def test_list_tensorboard_time_series_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.ListTensorboardTimeSeriesRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_time_series), "__call__" + ) as call: + call.return_value = tensorboard_service.ListTensorboardTimeSeriesResponse() + client.list_tensorboard_time_series(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_tensorboard_time_series_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.ListTensorboardTimeSeriesRequest() + + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_time_series), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardTimeSeriesResponse() + ) + await client.list_tensorboard_time_series(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_tensorboard_time_series_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardTimeSeriesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_tensorboard_time_series(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_tensorboard_time_series_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_time_series( + tensorboard_service.ListTensorboardTimeSeriesRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_tensorboard_time_series_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ListTensorboardTimeSeriesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ListTensorboardTimeSeriesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_tensorboard_time_series(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_tensorboard_time_series_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_tensorboard_time_series( + tensorboard_service.ListTensorboardTimeSeriesRequest(), + parent="parent_value", + ) + + +def test_list_tensorboard_time_series_pager(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_time_series), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + ], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_tensorboard_time_series(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all( + isinstance(i, tensorboard_time_series.TensorboardTimeSeries) + for i in results + ) + + +def test_list_tensorboard_time_series_pages(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_time_series), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + ], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + ], + ), + RuntimeError, + ) + pages = list(client.list_tensorboard_time_series(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_tensorboard_time_series_async_pager(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_time_series), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + ], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_tensorboard_time_series(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, tensorboard_time_series.TensorboardTimeSeries) + for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_tensorboard_time_series_async_pages(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tensorboard_time_series), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + ], + next_page_token="abc", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[], next_page_token="def", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + ], + next_page_token="ghi", + ), + tensorboard_service.ListTensorboardTimeSeriesResponse( + tensorboard_time_series=[ + tensorboard_time_series.TensorboardTimeSeries(), + tensorboard_time_series.TensorboardTimeSeries(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in ( + await client.list_tensorboard_time_series(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_tensorboard_time_series( + transport: str = "grpc", + request_type=tensorboard_service.DeleteTensorboardTimeSeriesRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_time_series), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.delete_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_delete_tensorboard_time_series_from_dict(): + test_delete_tensorboard_time_series(request_type=dict) + + +def test_delete_tensorboard_time_series_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_time_series), "__call__" + ) as call: + client.delete_tensorboard_time_series() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardTimeSeriesRequest() + + +@pytest.mark.asyncio +async def test_delete_tensorboard_time_series_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.DeleteTensorboardTimeSeriesRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_time_series), "__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_tensorboard_time_series(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.DeleteTensorboardTimeSeriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_delete_tensorboard_time_series_async_from_dict(): + await test_delete_tensorboard_time_series_async(request_type=dict) + + +def test_delete_tensorboard_time_series_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.DeleteTensorboardTimeSeriesRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_time_series), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.delete_tensorboard_time_series(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_tensorboard_time_series_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.DeleteTensorboardTimeSeriesRequest() + + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_time_series), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.delete_tensorboard_time_series(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_tensorboard_time_series_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_time_series), "__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_tensorboard_time_series(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_tensorboard_time_series_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_time_series( + tensorboard_service.DeleteTensorboardTimeSeriesRequest(), name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_tensorboard_time_series_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_tensorboard_time_series), "__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_tensorboard_time_series(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_tensorboard_time_series_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_tensorboard_time_series( + tensorboard_service.DeleteTensorboardTimeSeriesRequest(), name="name_value", + ) + + +def test_batch_read_tensorboard_time_series_data( + transport: str = "grpc", + request_type=tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest, +): + client = TensorboardServiceClient( + 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_read_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse() + ) + response = client.batch_read_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert ( + args[0] == tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance( + response, tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse + ) + + +def test_batch_read_tensorboard_time_series_data_from_dict(): + test_batch_read_tensorboard_time_series_data(request_type=dict) + + +def test_batch_read_tensorboard_time_series_data_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_read_tensorboard_time_series_data), "__call__" + ) as call: + client.batch_read_tensorboard_time_series_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert ( + args[0] == tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest() + ) + + +@pytest.mark.asyncio +async def test_batch_read_tensorboard_time_series_data_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest, +): + client = TensorboardServiceAsyncClient( + 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_read_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse() + ) + response = await client.batch_read_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert ( + args[0] == tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest() + ) + + # Establish that the response is the type that we expect. + assert isinstance( + response, tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse + ) + + +@pytest.mark.asyncio +async def test_batch_read_tensorboard_time_series_data_async_from_dict(): + await test_batch_read_tensorboard_time_series_data_async(request_type=dict) + + +def test_batch_read_tensorboard_time_series_data_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest() + + request.tensorboard = "tensorboard/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_read_tensorboard_time_series_data), "__call__" + ) as call: + call.return_value = ( + tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse() + ) + client.batch_read_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "tensorboard=tensorboard/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_batch_read_tensorboard_time_series_data_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest() + + request.tensorboard = "tensorboard/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_read_tensorboard_time_series_data), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse() + ) + await client.batch_read_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "tensorboard=tensorboard/value",) in kw["metadata"] + + +def test_batch_read_tensorboard_time_series_data_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_read_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_read_tensorboard_time_series_data(tensorboard="tensorboard_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].tensorboard + mock_val = "tensorboard_value" + assert arg == mock_val + + +def test_batch_read_tensorboard_time_series_data_flattened_error(): + client = TensorboardServiceClient( + 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.batch_read_tensorboard_time_series_data( + tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest(), + tensorboard="tensorboard_value", + ) + + +@pytest.mark.asyncio +async def test_batch_read_tensorboard_time_series_data_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_read_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.BatchReadTensorboardTimeSeriesDataResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_read_tensorboard_time_series_data( + tensorboard="tensorboard_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].tensorboard + mock_val = "tensorboard_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_batch_read_tensorboard_time_series_data_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_read_tensorboard_time_series_data( + tensorboard_service.BatchReadTensorboardTimeSeriesDataRequest(), + tensorboard="tensorboard_value", + ) + + +def test_read_tensorboard_time_series_data( + transport: str = "grpc", + request_type=tensorboard_service.ReadTensorboardTimeSeriesDataRequest, +): + client = TensorboardServiceClient( + 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.read_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ReadTensorboardTimeSeriesDataResponse() + response = client.read_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ReadTensorboardTimeSeriesDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance( + response, tensorboard_service.ReadTensorboardTimeSeriesDataResponse + ) + + +def test_read_tensorboard_time_series_data_from_dict(): + test_read_tensorboard_time_series_data(request_type=dict) + + +def test_read_tensorboard_time_series_data_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_time_series_data), "__call__" + ) as call: + client.read_tensorboard_time_series_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ReadTensorboardTimeSeriesDataRequest() + + +@pytest.mark.asyncio +async def test_read_tensorboard_time_series_data_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.ReadTensorboardTimeSeriesDataRequest, +): + client = TensorboardServiceAsyncClient( + 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.read_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ReadTensorboardTimeSeriesDataResponse() + ) + response = await client.read_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ReadTensorboardTimeSeriesDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance( + response, tensorboard_service.ReadTensorboardTimeSeriesDataResponse + ) + + +@pytest.mark.asyncio +async def test_read_tensorboard_time_series_data_async_from_dict(): + await test_read_tensorboard_time_series_data_async(request_type=dict) + + +def test_read_tensorboard_time_series_data_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.ReadTensorboardTimeSeriesDataRequest() + + request.tensorboard_time_series = "tensorboard_time_series/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_time_series_data), "__call__" + ) as call: + call.return_value = tensorboard_service.ReadTensorboardTimeSeriesDataResponse() + client.read_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "tensorboard_time_series=tensorboard_time_series/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_read_tensorboard_time_series_data_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.ReadTensorboardTimeSeriesDataRequest() + + request.tensorboard_time_series = "tensorboard_time_series/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_time_series_data), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ReadTensorboardTimeSeriesDataResponse() + ) + await client.read_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "tensorboard_time_series=tensorboard_time_series/value", + ) in kw["metadata"] + + +def test_read_tensorboard_time_series_data_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ReadTensorboardTimeSeriesDataResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.read_tensorboard_time_series_data( + tensorboard_time_series="tensorboard_time_series_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].tensorboard_time_series + mock_val = "tensorboard_time_series_value" + assert arg == mock_val + + +def test_read_tensorboard_time_series_data_flattened_error(): + client = TensorboardServiceClient( + 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.read_tensorboard_time_series_data( + tensorboard_service.ReadTensorboardTimeSeriesDataRequest(), + tensorboard_time_series="tensorboard_time_series_value", + ) + + +@pytest.mark.asyncio +async def test_read_tensorboard_time_series_data_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ReadTensorboardTimeSeriesDataResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ReadTensorboardTimeSeriesDataResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.read_tensorboard_time_series_data( + tensorboard_time_series="tensorboard_time_series_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].tensorboard_time_series + mock_val = "tensorboard_time_series_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_read_tensorboard_time_series_data_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.read_tensorboard_time_series_data( + tensorboard_service.ReadTensorboardTimeSeriesDataRequest(), + tensorboard_time_series="tensorboard_time_series_value", + ) + + +def test_read_tensorboard_blob_data( + transport: str = "grpc", + request_type=tensorboard_service.ReadTensorboardBlobDataRequest, +): + client = TensorboardServiceClient( + 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.read_tensorboard_blob_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = iter( + [tensorboard_service.ReadTensorboardBlobDataResponse()] + ) + response = client.read_tensorboard_blob_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ReadTensorboardBlobDataRequest() + + # Establish that the response is the type that we expect. + for message in response: + assert isinstance(message, tensorboard_service.ReadTensorboardBlobDataResponse) + + +def test_read_tensorboard_blob_data_from_dict(): + test_read_tensorboard_blob_data(request_type=dict) + + +def test_read_tensorboard_blob_data_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_blob_data), "__call__" + ) as call: + client.read_tensorboard_blob_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ReadTensorboardBlobDataRequest() + + +@pytest.mark.asyncio +async def test_read_tensorboard_blob_data_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.ReadTensorboardBlobDataRequest, +): + client = TensorboardServiceAsyncClient( + 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.read_tensorboard_blob_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True) + call.return_value.read = mock.AsyncMock( + side_effect=[tensorboard_service.ReadTensorboardBlobDataResponse()] + ) + response = await client.read_tensorboard_blob_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ReadTensorboardBlobDataRequest() + + # Establish that the response is the type that we expect. + message = await response.read() + assert isinstance(message, tensorboard_service.ReadTensorboardBlobDataResponse) + + +@pytest.mark.asyncio +async def test_read_tensorboard_blob_data_async_from_dict(): + await test_read_tensorboard_blob_data_async(request_type=dict) + + +def test_read_tensorboard_blob_data_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.ReadTensorboardBlobDataRequest() + + request.time_series = "time_series/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_blob_data), "__call__" + ) as call: + call.return_value = iter( + [tensorboard_service.ReadTensorboardBlobDataResponse()] + ) + client.read_tensorboard_blob_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "time_series=time_series/value",) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_read_tensorboard_blob_data_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.ReadTensorboardBlobDataRequest() + + request.time_series = "time_series/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_blob_data), "__call__" + ) as call: + call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True) + call.return_value.read = mock.AsyncMock( + side_effect=[tensorboard_service.ReadTensorboardBlobDataResponse()] + ) + await client.read_tensorboard_blob_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "time_series=time_series/value",) in kw["metadata"] + + +def test_read_tensorboard_blob_data_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_blob_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = iter( + [tensorboard_service.ReadTensorboardBlobDataResponse()] + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.read_tensorboard_blob_data(time_series="time_series_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].time_series + mock_val = "time_series_value" + assert arg == mock_val + + +def test_read_tensorboard_blob_data_flattened_error(): + client = TensorboardServiceClient( + 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.read_tensorboard_blob_data( + tensorboard_service.ReadTensorboardBlobDataRequest(), + time_series="time_series_value", + ) + + +@pytest.mark.asyncio +async def test_read_tensorboard_blob_data_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.read_tensorboard_blob_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = iter( + [tensorboard_service.ReadTensorboardBlobDataResponse()] + ) + + call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.read_tensorboard_blob_data( + time_series="time_series_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].time_series + mock_val = "time_series_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_read_tensorboard_blob_data_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.read_tensorboard_blob_data( + tensorboard_service.ReadTensorboardBlobDataRequest(), + time_series="time_series_value", + ) + + +def test_write_tensorboard_experiment_data( + transport: str = "grpc", + request_type=tensorboard_service.WriteTensorboardExperimentDataRequest, +): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_experiment_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.WriteTensorboardExperimentDataResponse() + response = client.write_tensorboard_experiment_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.WriteTensorboardExperimentDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance( + response, tensorboard_service.WriteTensorboardExperimentDataResponse + ) + + +def test_write_tensorboard_experiment_data_from_dict(): + test_write_tensorboard_experiment_data(request_type=dict) + + +def test_write_tensorboard_experiment_data_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_experiment_data), "__call__" + ) as call: + client.write_tensorboard_experiment_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.WriteTensorboardExperimentDataRequest() + + +@pytest.mark.asyncio +async def test_write_tensorboard_experiment_data_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.WriteTensorboardExperimentDataRequest, +): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_experiment_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.WriteTensorboardExperimentDataResponse() + ) + response = await client.write_tensorboard_experiment_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.WriteTensorboardExperimentDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance( + response, tensorboard_service.WriteTensorboardExperimentDataResponse + ) + + +@pytest.mark.asyncio +async def test_write_tensorboard_experiment_data_async_from_dict(): + await test_write_tensorboard_experiment_data_async(request_type=dict) + + +def test_write_tensorboard_experiment_data_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.WriteTensorboardExperimentDataRequest() + + request.tensorboard_experiment = "tensorboard_experiment/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_experiment_data), "__call__" + ) as call: + call.return_value = tensorboard_service.WriteTensorboardExperimentDataResponse() + client.write_tensorboard_experiment_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "tensorboard_experiment=tensorboard_experiment/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_write_tensorboard_experiment_data_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.WriteTensorboardExperimentDataRequest() + + request.tensorboard_experiment = "tensorboard_experiment/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_experiment_data), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.WriteTensorboardExperimentDataResponse() + ) + await client.write_tensorboard_experiment_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "tensorboard_experiment=tensorboard_experiment/value", + ) in kw["metadata"] + + +def test_write_tensorboard_experiment_data_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_experiment_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.WriteTensorboardExperimentDataResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.write_tensorboard_experiment_data( + tensorboard_experiment="tensorboard_experiment_value", + write_run_data_requests=[ + tensorboard_service.WriteTensorboardRunDataRequest( + tensorboard_run="tensorboard_run_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].tensorboard_experiment + mock_val = "tensorboard_experiment_value" + assert arg == mock_val + arg = args[0].write_run_data_requests + mock_val = [ + tensorboard_service.WriteTensorboardRunDataRequest( + tensorboard_run="tensorboard_run_value" + ) + ] + assert arg == mock_val + + +def test_write_tensorboard_experiment_data_flattened_error(): + client = TensorboardServiceClient( + 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.write_tensorboard_experiment_data( + tensorboard_service.WriteTensorboardExperimentDataRequest(), + tensorboard_experiment="tensorboard_experiment_value", + write_run_data_requests=[ + tensorboard_service.WriteTensorboardRunDataRequest( + tensorboard_run="tensorboard_run_value" + ) + ], + ) + + +@pytest.mark.asyncio +async def test_write_tensorboard_experiment_data_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_experiment_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.WriteTensorboardExperimentDataResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.WriteTensorboardExperimentDataResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.write_tensorboard_experiment_data( + tensorboard_experiment="tensorboard_experiment_value", + write_run_data_requests=[ + tensorboard_service.WriteTensorboardRunDataRequest( + tensorboard_run="tensorboard_run_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].tensorboard_experiment + mock_val = "tensorboard_experiment_value" + assert arg == mock_val + arg = args[0].write_run_data_requests + mock_val = [ + tensorboard_service.WriteTensorboardRunDataRequest( + tensorboard_run="tensorboard_run_value" + ) + ] + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_write_tensorboard_experiment_data_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.write_tensorboard_experiment_data( + tensorboard_service.WriteTensorboardExperimentDataRequest(), + tensorboard_experiment="tensorboard_experiment_value", + write_run_data_requests=[ + tensorboard_service.WriteTensorboardRunDataRequest( + tensorboard_run="tensorboard_run_value" + ) + ], + ) + + +def test_write_tensorboard_run_data( + transport: str = "grpc", + request_type=tensorboard_service.WriteTensorboardRunDataRequest, +): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_run_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.WriteTensorboardRunDataResponse() + response = client.write_tensorboard_run_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.WriteTensorboardRunDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_service.WriteTensorboardRunDataResponse) + + +def test_write_tensorboard_run_data_from_dict(): + test_write_tensorboard_run_data(request_type=dict) + + +def test_write_tensorboard_run_data_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_run_data), "__call__" + ) as call: + client.write_tensorboard_run_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.WriteTensorboardRunDataRequest() + + +@pytest.mark.asyncio +async def test_write_tensorboard_run_data_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.WriteTensorboardRunDataRequest, +): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_run_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.WriteTensorboardRunDataResponse() + ) + response = await client.write_tensorboard_run_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.WriteTensorboardRunDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, tensorboard_service.WriteTensorboardRunDataResponse) + + +@pytest.mark.asyncio +async def test_write_tensorboard_run_data_async_from_dict(): + await test_write_tensorboard_run_data_async(request_type=dict) + + +def test_write_tensorboard_run_data_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.WriteTensorboardRunDataRequest() + + request.tensorboard_run = "tensorboard_run/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_run_data), "__call__" + ) as call: + call.return_value = tensorboard_service.WriteTensorboardRunDataResponse() + client.write_tensorboard_run_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "tensorboard_run=tensorboard_run/value",) in kw[ + "metadata" + ] + + +@pytest.mark.asyncio +async def test_write_tensorboard_run_data_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.WriteTensorboardRunDataRequest() + + request.tensorboard_run = "tensorboard_run/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_run_data), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.WriteTensorboardRunDataResponse() + ) + await client.write_tensorboard_run_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "tensorboard_run=tensorboard_run/value",) in kw[ + "metadata" + ] + + +def test_write_tensorboard_run_data_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_run_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.WriteTensorboardRunDataResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.write_tensorboard_run_data( + tensorboard_run="tensorboard_run_value", + time_series_data=[ + tensorboard_data.TimeSeriesData( + tensorboard_time_series_id="tensorboard_time_series_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].tensorboard_run + mock_val = "tensorboard_run_value" + assert arg == mock_val + arg = args[0].time_series_data + mock_val = [ + tensorboard_data.TimeSeriesData( + tensorboard_time_series_id="tensorboard_time_series_id_value" + ) + ] + assert arg == mock_val + + +def test_write_tensorboard_run_data_flattened_error(): + client = TensorboardServiceClient( + 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.write_tensorboard_run_data( + tensorboard_service.WriteTensorboardRunDataRequest(), + tensorboard_run="tensorboard_run_value", + time_series_data=[ + tensorboard_data.TimeSeriesData( + tensorboard_time_series_id="tensorboard_time_series_id_value" + ) + ], + ) + + +@pytest.mark.asyncio +async def test_write_tensorboard_run_data_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_tensorboard_run_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.WriteTensorboardRunDataResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.WriteTensorboardRunDataResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.write_tensorboard_run_data( + tensorboard_run="tensorboard_run_value", + time_series_data=[ + tensorboard_data.TimeSeriesData( + tensorboard_time_series_id="tensorboard_time_series_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].tensorboard_run + mock_val = "tensorboard_run_value" + assert arg == mock_val + arg = args[0].time_series_data + mock_val = [ + tensorboard_data.TimeSeriesData( + tensorboard_time_series_id="tensorboard_time_series_id_value" + ) + ] + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_write_tensorboard_run_data_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.write_tensorboard_run_data( + tensorboard_service.WriteTensorboardRunDataRequest(), + tensorboard_run="tensorboard_run_value", + time_series_data=[ + tensorboard_data.TimeSeriesData( + tensorboard_time_series_id="tensorboard_time_series_id_value" + ) + ], + ) + + +def test_export_tensorboard_time_series_data( + transport: str = "grpc", + request_type=tensorboard_service.ExportTensorboardTimeSeriesDataRequest, +): + client = TensorboardServiceClient( + 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_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + next_page_token="next_page_token_value", + ) + response = client.export_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ExportTensorboardTimeSeriesDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ExportTensorboardTimeSeriesDataPager) + assert response.next_page_token == "next_page_token_value" + + +def test_export_tensorboard_time_series_data_from_dict(): + test_export_tensorboard_time_series_data(request_type=dict) + + +def test_export_tensorboard_time_series_data_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_tensorboard_time_series_data), "__call__" + ) as call: + client.export_tensorboard_time_series_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ExportTensorboardTimeSeriesDataRequest() + + +@pytest.mark.asyncio +async def test_export_tensorboard_time_series_data_async( + transport: str = "grpc_asyncio", + request_type=tensorboard_service.ExportTensorboardTimeSeriesDataRequest, +): + client = TensorboardServiceAsyncClient( + 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_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.export_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == tensorboard_service.ExportTensorboardTimeSeriesDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ExportTensorboardTimeSeriesDataAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_export_tensorboard_time_series_data_async_from_dict(): + await test_export_tensorboard_time_series_data_async(request_type=dict) + + +def test_export_tensorboard_time_series_data_field_headers(): + client = TensorboardServiceClient( + 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 = tensorboard_service.ExportTensorboardTimeSeriesDataRequest() + + request.tensorboard_time_series = "tensorboard_time_series/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_tensorboard_time_series_data), "__call__" + ) as call: + call.return_value = ( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse() + ) + client.export_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "tensorboard_time_series=tensorboard_time_series/value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_export_tensorboard_time_series_data_field_headers_async(): + client = TensorboardServiceAsyncClient( + 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 = tensorboard_service.ExportTensorboardTimeSeriesDataRequest() + + request.tensorboard_time_series = "tensorboard_time_series/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_tensorboard_time_series_data), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse() + ) + await client.export_tensorboard_time_series_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "tensorboard_time_series=tensorboard_time_series/value", + ) in kw["metadata"] + + +def test_export_tensorboard_time_series_data_flattened(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.export_tensorboard_time_series_data( + tensorboard_time_series="tensorboard_time_series_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].tensorboard_time_series + mock_val = "tensorboard_time_series_value" + assert arg == mock_val + + +def test_export_tensorboard_time_series_data_flattened_error(): + client = TensorboardServiceClient( + 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_tensorboard_time_series_data( + tensorboard_service.ExportTensorboardTimeSeriesDataRequest(), + tensorboard_time_series="tensorboard_time_series_value", + ) + + +@pytest.mark.asyncio +async def test_export_tensorboard_time_series_data_flattened_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_tensorboard_time_series_data), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = ( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse() + ) + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.export_tensorboard_time_series_data( + tensorboard_time_series="tensorboard_time_series_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].tensorboard_time_series + mock_val = "tensorboard_time_series_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_export_tensorboard_time_series_data_flattened_error_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.export_tensorboard_time_series_data( + tensorboard_service.ExportTensorboardTimeSeriesDataRequest(), + tensorboard_time_series="tensorboard_time_series_value", + ) + + +def test_export_tensorboard_time_series_data_pager(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_tensorboard_time_series_data), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[ + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + ], + next_page_token="abc", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[], next_page_token="def", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[tensorboard_data.TimeSeriesDataPoint(),], + next_page_token="ghi", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[ + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tensorboard_time_series", ""),) + ), + ) + pager = client.export_tensorboard_time_series_data(request={}) + + assert pager._metadata == metadata + + results = [i for i in pager] + assert len(results) == 6 + assert all(isinstance(i, tensorboard_data.TimeSeriesDataPoint) for i in results) + + +def test_export_tensorboard_time_series_data_pages(): + client = TensorboardServiceClient(credentials=ga_credentials.AnonymousCredentials,) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_tensorboard_time_series_data), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[ + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + ], + next_page_token="abc", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[], next_page_token="def", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[tensorboard_data.TimeSeriesDataPoint(),], + next_page_token="ghi", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[ + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + ], + ), + RuntimeError, + ) + pages = list(client.export_tensorboard_time_series_data(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_export_tensorboard_time_series_data_async_pager(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_tensorboard_time_series_data), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[ + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + ], + next_page_token="abc", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[], next_page_token="def", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[tensorboard_data.TimeSeriesDataPoint(),], + next_page_token="ghi", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[ + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + ], + ), + RuntimeError, + ) + async_pager = await client.export_tensorboard_time_series_data(request={},) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, tensorboard_data.TimeSeriesDataPoint) for i in responses + ) + + +@pytest.mark.asyncio +async def test_export_tensorboard_time_series_data_async_pages(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.export_tensorboard_time_series_data), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[ + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + ], + next_page_token="abc", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[], next_page_token="def", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[tensorboard_data.TimeSeriesDataPoint(),], + next_page_token="ghi", + ), + tensorboard_service.ExportTensorboardTimeSeriesDataResponse( + time_series_data_points=[ + tensorboard_data.TimeSeriesDataPoint(), + tensorboard_data.TimeSeriesDataPoint(), + ], + ), + RuntimeError, + ) + pages = [] + async for page_ in ( + await client.export_tensorboard_time_series_data(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.TensorboardServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.TensorboardServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TensorboardServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.TensorboardServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TensorboardServiceClient( + client_options={"scopes": ["1", "2"]}, transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.TensorboardServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = TensorboardServiceClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.TensorboardServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.TensorboardServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.TensorboardServiceGrpcTransport, + transports.TensorboardServiceGrpcAsyncIOTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance(client.transport, transports.TensorboardServiceGrpcTransport,) + + +def test_tensorboard_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.TensorboardServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_tensorboard_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.aiplatform_v1.services.tensorboard_service.transports.TensorboardServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.TensorboardServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_tensorboard", + "get_tensorboard", + "update_tensorboard", + "list_tensorboards", + "delete_tensorboard", + "create_tensorboard_experiment", + "get_tensorboard_experiment", + "update_tensorboard_experiment", + "list_tensorboard_experiments", + "delete_tensorboard_experiment", + "create_tensorboard_run", + "batch_create_tensorboard_runs", + "get_tensorboard_run", + "update_tensorboard_run", + "list_tensorboard_runs", + "delete_tensorboard_run", + "batch_create_tensorboard_time_series", + "create_tensorboard_time_series", + "get_tensorboard_time_series", + "update_tensorboard_time_series", + "list_tensorboard_time_series", + "delete_tensorboard_time_series", + "batch_read_tensorboard_time_series_data", + "read_tensorboard_time_series_data", + "read_tensorboard_blob_data", + "write_tensorboard_experiment_data", + "write_tensorboard_run_data", + "export_tensorboard_time_series_data", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + +def test_tensorboard_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.aiplatform_v1.services.tensorboard_service.transports.TensorboardServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.TensorboardServiceTransport( + 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", + "https://www.googleapis.com/auth/cloud-platform.read-only", + ), + quota_project_id="octopus", + ) + + +def test_tensorboard_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.aiplatform_v1.services.tensorboard_service.transports.TensorboardServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.TensorboardServiceTransport() + adc.assert_called_once() + + +def test_tensorboard_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) + TensorboardServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + ), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.TensorboardServiceGrpcTransport, + transports.TensorboardServiceGrpcAsyncIOTransport, + ], +) +def test_tensorboard_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", + "https://www.googleapis.com/auth/cloud-platform.read-only", + ), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.TensorboardServiceGrpcTransport, grpc_helpers), + (transports.TensorboardServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_tensorboard_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( + "aiplatform.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + ), + scopes=["1", "2"], + default_host="aiplatform.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.TensorboardServiceGrpcTransport, + transports.TensorboardServiceGrpcAsyncIOTransport, + ], +) +def test_tensorboard_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_tensorboard_service_host_no_port(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="aiplatform.googleapis.com" + ), + ) + assert client.transport._host == "aiplatform.googleapis.com:443" + + +def test_tensorboard_service_host_with_port(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="aiplatform.googleapis.com:8000" + ), + ) + assert client.transport._host == "aiplatform.googleapis.com:8000" + + +def test_tensorboard_service_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.TensorboardServiceGrpcTransport( + 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_tensorboard_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.TensorboardServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [ + transports.TensorboardServiceGrpcTransport, + transports.TensorboardServiceGrpcAsyncIOTransport, + ], +) +def test_tensorboard_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.TensorboardServiceGrpcTransport, + transports.TensorboardServiceGrpcAsyncIOTransport, + ], +) +def test_tensorboard_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_tensorboard_service_grpc_lro_client(): + client = TensorboardServiceClient( + 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_tensorboard_service_grpc_lro_async_client(): + client = TensorboardServiceAsyncClient( + 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_tensorboard_path(): + project = "squid" + location = "clam" + tensorboard = "whelk" + expected = "projects/{project}/locations/{location}/tensorboards/{tensorboard}".format( + project=project, location=location, tensorboard=tensorboard, + ) + actual = TensorboardServiceClient.tensorboard_path(project, location, tensorboard) + assert expected == actual + + +def test_parse_tensorboard_path(): + expected = { + "project": "octopus", + "location": "oyster", + "tensorboard": "nudibranch", + } + path = TensorboardServiceClient.tensorboard_path(**expected) + + # Check that the path construction is reversible. + actual = TensorboardServiceClient.parse_tensorboard_path(path) + assert expected == actual + + +def test_tensorboard_experiment_path(): + project = "cuttlefish" + location = "mussel" + tensorboard = "winkle" + experiment = "nautilus" + expected = "projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}".format( + project=project, + location=location, + tensorboard=tensorboard, + experiment=experiment, + ) + actual = TensorboardServiceClient.tensorboard_experiment_path( + project, location, tensorboard, experiment + ) + assert expected == actual + + +def test_parse_tensorboard_experiment_path(): + expected = { + "project": "scallop", + "location": "abalone", + "tensorboard": "squid", + "experiment": "clam", + } + path = TensorboardServiceClient.tensorboard_experiment_path(**expected) + + # Check that the path construction is reversible. + actual = TensorboardServiceClient.parse_tensorboard_experiment_path(path) + assert expected == actual + + +def test_tensorboard_run_path(): + project = "whelk" + location = "octopus" + tensorboard = "oyster" + experiment = "nudibranch" + run = "cuttlefish" + expected = "projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}".format( + project=project, + location=location, + tensorboard=tensorboard, + experiment=experiment, + run=run, + ) + actual = TensorboardServiceClient.tensorboard_run_path( + project, location, tensorboard, experiment, run + ) + assert expected == actual + + +def test_parse_tensorboard_run_path(): + expected = { + "project": "mussel", + "location": "winkle", + "tensorboard": "nautilus", + "experiment": "scallop", + "run": "abalone", + } + path = TensorboardServiceClient.tensorboard_run_path(**expected) + + # Check that the path construction is reversible. + actual = TensorboardServiceClient.parse_tensorboard_run_path(path) + assert expected == actual + + +def test_tensorboard_time_series_path(): + project = "squid" + location = "clam" + tensorboard = "whelk" + experiment = "octopus" + run = "oyster" + time_series = "nudibranch" + expected = "projects/{project}/locations/{location}/tensorboards/{tensorboard}/experiments/{experiment}/runs/{run}/timeSeries/{time_series}".format( + project=project, + location=location, + tensorboard=tensorboard, + experiment=experiment, + run=run, + time_series=time_series, + ) + actual = TensorboardServiceClient.tensorboard_time_series_path( + project, location, tensorboard, experiment, run, time_series + ) + assert expected == actual + + +def test_parse_tensorboard_time_series_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + "tensorboard": "winkle", + "experiment": "nautilus", + "run": "scallop", + "time_series": "abalone", + } + path = TensorboardServiceClient.tensorboard_time_series_path(**expected) + + # Check that the path construction is reversible. + actual = TensorboardServiceClient.parse_tensorboard_time_series_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = TensorboardServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = TensorboardServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = TensorboardServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format(folder=folder,) + actual = TensorboardServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = TensorboardServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = TensorboardServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format(organization=organization,) + actual = TensorboardServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = TensorboardServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = TensorboardServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format(project=project,) + actual = TensorboardServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = TensorboardServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = TensorboardServiceClient.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 = TensorboardServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = TensorboardServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = TensorboardServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_withDEFAULT_CLIENT_INFO(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.TensorboardServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.TensorboardServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = TensorboardServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = TensorboardServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = TensorboardServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = TensorboardServiceClient( + 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() diff --git a/tests/unit/gapic/aiplatform_v1/test_vizier_service.py b/tests/unit/gapic/aiplatform_v1/test_vizier_service.py index 500aa9c046..5050a30807 100644 --- a/tests/unit/gapic/aiplatform_v1/test_vizier_service.py +++ b/tests/unit/gapic/aiplatform_v1/test_vizier_service.py @@ -651,8 +651,12 @@ def test_create_study_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].study == gca_study.Study(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].study + mock_val = gca_study.Study(name="name_value") + assert arg == mock_val def test_create_study_flattened_error(): @@ -690,8 +694,12 @@ async def test_create_study_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].study == gca_study.Study(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].study + mock_val = gca_study.Study(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -873,7 +881,9 @@ def test_get_study_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_study_flattened_error(): @@ -907,7 +917,9 @@ async def test_get_study_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1075,7 +1087,9 @@ def test_list_studies_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_studies_flattened_error(): @@ -1111,7 +1125,9 @@ async def test_list_studies_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1393,7 +1409,9 @@ def test_delete_study_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_study_flattened_error(): @@ -1427,7 +1445,9 @@ async def test_delete_study_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1607,7 +1627,9 @@ def test_lookup_study_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_lookup_study_flattened_error(): @@ -1641,7 +1663,9 @@ async def test_lookup_study_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1963,8 +1987,12 @@ def test_create_trial_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].trial == study.Trial(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].trial + mock_val = study.Trial(name="name_value") + assert arg == mock_val def test_create_trial_flattened_error(): @@ -2002,8 +2030,12 @@ async def test_create_trial_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].trial == study.Trial(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].trial + mock_val = study.Trial(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -2193,7 +2225,9 @@ def test_get_trial_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_trial_flattened_error(): @@ -2227,7 +2261,9 @@ async def test_get_trial_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2395,7 +2431,9 @@ def test_list_trials_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_trials_flattened_error(): @@ -2431,7 +2469,9 @@ async def test_list_trials_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3028,7 +3068,9 @@ def test_delete_trial_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_trial_flattened_error(): @@ -3062,7 +3104,9 @@ async def test_delete_trial_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3539,7 +3583,9 @@ def test_list_optimal_trials_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_optimal_trials_flattened_error(): @@ -3577,7 +3623,9 @@ async def test_list_optimal_trials_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_dataset_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_dataset_service.py index 267d6d2818..b3c8578507 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_dataset_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_dataset_service.py @@ -645,8 +645,12 @@ def test_create_dataset_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].dataset == gca_dataset.Dataset(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].dataset + mock_val = gca_dataset.Dataset(name="name_value") + assert arg == mock_val def test_create_dataset_flattened_error(): @@ -686,8 +690,12 @@ async def test_create_dataset_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].dataset == gca_dataset.Dataset(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].dataset + mock_val = gca_dataset.Dataset(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -873,7 +881,9 @@ def test_get_dataset_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_dataset_flattened_error(): @@ -907,7 +917,9 @@ async def test_get_dataset_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1098,8 +1110,12 @@ def test_update_dataset_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].dataset == gca_dataset.Dataset(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].dataset + mock_val = gca_dataset.Dataset(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_dataset_flattened_error(): @@ -1138,8 +1154,12 @@ async def test_update_dataset_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].dataset == gca_dataset.Dataset(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].dataset + mock_val = gca_dataset.Dataset(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 @@ -1311,7 +1331,9 @@ def test_list_datasets_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_datasets_flattened_error(): @@ -1347,7 +1369,9 @@ async def test_list_datasets_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1633,7 +1657,9 @@ def test_delete_dataset_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_dataset_flattened_error(): @@ -1669,7 +1695,9 @@ async def test_delete_dataset_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1838,10 +1866,14 @@ def test_import_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].import_configs == [ + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].import_configs + mock_val = [ dataset.ImportDataConfig(gcs_source=io.GcsSource(uris=["uris_value"])) ] + assert arg == mock_val def test_import_data_flattened_error(): @@ -1886,10 +1918,14 @@ async def test_import_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].import_configs == [ + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].import_configs + mock_val = [ dataset.ImportDataConfig(gcs_source=io.GcsSource(uris=["uris_value"])) ] + assert arg == mock_val @pytest.mark.asyncio @@ -2064,12 +2100,16 @@ def test_export_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].export_config == dataset.ExportDataConfig( + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].export_config + mock_val = dataset.ExportDataConfig( gcs_destination=io.GcsDestination( output_uri_prefix="output_uri_prefix_value" ) ) + assert arg == mock_val def test_export_data_flattened_error(): @@ -2118,12 +2158,16 @@ async def test_export_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].export_config == dataset.ExportDataConfig( + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].export_config + mock_val = dataset.ExportDataConfig( gcs_destination=io.GcsDestination( output_uri_prefix="output_uri_prefix_value" ) ) + assert arg == mock_val @pytest.mark.asyncio @@ -2299,7 +2343,9 @@ def test_list_data_items_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_data_items_flattened_error(): @@ -2335,7 +2381,9 @@ async def test_list_data_items_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2668,7 +2716,9 @@ def test_get_annotation_spec_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_annotation_spec_flattened_error(): @@ -2706,7 +2756,9 @@ async def test_get_annotation_spec_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2876,7 +2928,9 @@ def test_list_annotations_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_annotations_flattened_error(): @@ -2912,7 +2966,9 @@ async def test_list_annotations_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_endpoint_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_endpoint_service.py index f5bca45e98..7c59752cf7 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_endpoint_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_endpoint_service.py @@ -649,15 +649,24 @@ def test_create_endpoint_flattened(): # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.create_endpoint( - parent="parent_value", endpoint=gca_endpoint.Endpoint(name="name_value"), + parent="parent_value", + endpoint=gca_endpoint.Endpoint(name="name_value"), + endpoint_id="endpoint_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] - assert args[0].parent == "parent_value" - assert args[0].endpoint == gca_endpoint.Endpoint(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].endpoint + mock_val = gca_endpoint.Endpoint(name="name_value") + assert arg == mock_val + arg = args[0].endpoint_id + mock_val = "endpoint_id_value" + assert arg == mock_val def test_create_endpoint_flattened_error(): @@ -670,6 +679,7 @@ def test_create_endpoint_flattened_error(): endpoint_service.CreateEndpointRequest(), parent="parent_value", endpoint=gca_endpoint.Endpoint(name="name_value"), + endpoint_id="endpoint_id_value", ) @@ -690,15 +700,24 @@ async def test_create_endpoint_flattened_async(): # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. response = await client.create_endpoint( - parent="parent_value", endpoint=gca_endpoint.Endpoint(name="name_value"), + parent="parent_value", + endpoint=gca_endpoint.Endpoint(name="name_value"), + endpoint_id="endpoint_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] - assert args[0].parent == "parent_value" - assert args[0].endpoint == gca_endpoint.Endpoint(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].endpoint + mock_val = gca_endpoint.Endpoint(name="name_value") + assert arg == mock_val + arg = args[0].endpoint_id + mock_val = "endpoint_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -714,6 +733,7 @@ async def test_create_endpoint_flattened_error_async(): endpoint_service.CreateEndpointRequest(), parent="parent_value", endpoint=gca_endpoint.Endpoint(name="name_value"), + endpoint_id="endpoint_id_value", ) @@ -737,6 +757,7 @@ def test_get_endpoint( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, model_deployment_monitoring_job="model_deployment_monitoring_job_value", ) response = client.get_endpoint(request) @@ -753,6 +774,7 @@ def test_get_endpoint( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True assert ( response.model_deployment_monitoring_job == "model_deployment_monitoring_job_value" @@ -800,6 +822,7 @@ async def test_get_endpoint_async( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, model_deployment_monitoring_job="model_deployment_monitoring_job_value", ) ) @@ -817,6 +840,7 @@ async def test_get_endpoint_async( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True assert ( response.model_deployment_monitoring_job == "model_deployment_monitoring_job_value" @@ -894,7 +918,9 @@ def test_get_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_endpoint_flattened_error(): @@ -928,7 +954,9 @@ async def test_get_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1098,7 +1126,9 @@ def test_list_endpoints_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_endpoints_flattened_error(): @@ -1134,7 +1164,9 @@ async def test_list_endpoints_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1321,6 +1353,7 @@ def test_update_endpoint( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, model_deployment_monitoring_job="model_deployment_monitoring_job_value", ) response = client.update_endpoint(request) @@ -1337,6 +1370,7 @@ def test_update_endpoint( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True assert ( response.model_deployment_monitoring_job == "model_deployment_monitoring_job_value" @@ -1384,6 +1418,7 @@ async def test_update_endpoint_async( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, model_deployment_monitoring_job="model_deployment_monitoring_job_value", ) ) @@ -1401,6 +1436,7 @@ async def test_update_endpoint_async( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True assert ( response.model_deployment_monitoring_job == "model_deployment_monitoring_job_value" @@ -1487,8 +1523,12 @@ def test_update_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].endpoint == gca_endpoint.Endpoint(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].endpoint + mock_val = gca_endpoint.Endpoint(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_endpoint_flattened_error(): @@ -1529,8 +1569,12 @@ async def test_update_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].endpoint == gca_endpoint.Endpoint(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].endpoint + mock_val = gca_endpoint.Endpoint(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 @@ -1696,7 +1740,9 @@ def test_delete_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_endpoint_flattened_error(): @@ -1732,7 +1778,9 @@ async def test_delete_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1906,15 +1954,21 @@ def test_deploy_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].deployed_model == gca_endpoint.DeployedModel( + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].deployed_model + mock_val = gca_endpoint.DeployedModel( dedicated_resources=machine_resources.DedicatedResources( machine_spec=machine_resources.MachineSpec( machine_type="machine_type_value" ) ) ) - assert args[0].traffic_split == {"key_value": 541} + assert arg == mock_val + arg = args[0].traffic_split + mock_val = {"key_value": 541} + assert arg == mock_val def test_deploy_model_flattened_error(): @@ -1969,15 +2023,21 @@ async def test_deploy_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].deployed_model == gca_endpoint.DeployedModel( + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].deployed_model + mock_val = gca_endpoint.DeployedModel( dedicated_resources=machine_resources.DedicatedResources( machine_spec=machine_resources.MachineSpec( machine_type="machine_type_value" ) ) ) - assert args[0].traffic_split == {"key_value": 541} + assert arg == mock_val + arg = args[0].traffic_split + mock_val = {"key_value": 541} + assert arg == mock_val @pytest.mark.asyncio @@ -2154,9 +2214,15 @@ def test_undeploy_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].deployed_model_id == "deployed_model_id_value" - assert args[0].traffic_split == {"key_value": 541} + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].deployed_model_id + mock_val = "deployed_model_id_value" + assert arg == mock_val + arg = args[0].traffic_split + mock_val = {"key_value": 541} + assert arg == mock_val def test_undeploy_model_flattened_error(): @@ -2199,9 +2265,15 @@ async def test_undeploy_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].deployed_model_id == "deployed_model_id_value" - assert args[0].traffic_split == {"key_value": 541} + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].deployed_model_id + mock_val = "deployed_model_id_value" + assert arg == mock_val + arg = args[0].traffic_split + mock_val = {"key_value": 541} + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_featurestore_online_serving_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_featurestore_online_serving_service.py index 7481c87398..364971192d 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_featurestore_online_serving_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_featurestore_online_serving_service.py @@ -698,7 +698,9 @@ def test_read_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val def test_read_feature_values_flattened_error(): @@ -739,7 +741,9 @@ async def test_read_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val @pytest.mark.asyncio @@ -940,7 +944,9 @@ def test_streaming_read_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val def test_streaming_read_feature_values_flattened_error(): @@ -983,7 +989,9 @@ async def test_streaming_read_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_featurestore_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_featurestore_service.py index 99da020e74..392021dcb0 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_featurestore_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_featurestore_service.py @@ -684,14 +684,22 @@ def test_create_featurestore_flattened(): client.create_featurestore( parent="parent_value", featurestore=gca_featurestore.Featurestore(name="name_value"), + featurestore_id="featurestore_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] - assert args[0].parent == "parent_value" - assert args[0].featurestore == gca_featurestore.Featurestore(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].featurestore + mock_val = gca_featurestore.Featurestore(name="name_value") + assert arg == mock_val + arg = args[0].featurestore_id + mock_val = "featurestore_id_value" + assert arg == mock_val def test_create_featurestore_flattened_error(): @@ -706,6 +714,7 @@ def test_create_featurestore_flattened_error(): featurestore_service.CreateFeaturestoreRequest(), parent="parent_value", featurestore=gca_featurestore.Featurestore(name="name_value"), + featurestore_id="featurestore_id_value", ) @@ -730,14 +739,22 @@ async def test_create_featurestore_flattened_async(): response = await client.create_featurestore( parent="parent_value", featurestore=gca_featurestore.Featurestore(name="name_value"), + featurestore_id="featurestore_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] - assert args[0].parent == "parent_value" - assert args[0].featurestore == gca_featurestore.Featurestore(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].featurestore + mock_val = gca_featurestore.Featurestore(name="name_value") + assert arg == mock_val + arg = args[0].featurestore_id + mock_val = "featurestore_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -753,6 +770,7 @@ async def test_create_featurestore_flattened_error_async(): featurestore_service.CreateFeaturestoreRequest(), parent="parent_value", featurestore=gca_featurestore.Featurestore(name="name_value"), + featurestore_id="featurestore_id_value", ) @@ -922,7 +940,9 @@ def test_get_featurestore_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_featurestore_flattened_error(): @@ -960,7 +980,9 @@ async def test_get_featurestore_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1147,7 +1169,9 @@ def test_list_featurestores_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_featurestores_flattened_error(): @@ -1187,7 +1211,9 @@ async def test_list_featurestores_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1547,8 +1573,12 @@ def test_update_featurestore_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].featurestore == gca_featurestore.Featurestore(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].featurestore + mock_val = gca_featurestore.Featurestore(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_featurestore_flattened_error(): @@ -1593,8 +1623,12 @@ async def test_update_featurestore_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].featurestore == gca_featurestore.Featurestore(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].featurestore + mock_val = gca_featurestore.Featurestore(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 @@ -1779,8 +1813,12 @@ def test_delete_featurestore_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].force == True + 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_featurestore_flattened_error(): @@ -1822,8 +1860,12 @@ async def test_delete_featurestore_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].force == True + 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 @@ -2003,14 +2045,22 @@ def test_create_entity_type_flattened(): client.create_entity_type( parent="parent_value", entity_type=gca_entity_type.EntityType(name="name_value"), + entity_type_id="entity_type_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] - assert args[0].parent == "parent_value" - assert args[0].entity_type == gca_entity_type.EntityType(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].entity_type + mock_val = gca_entity_type.EntityType(name="name_value") + assert arg == mock_val + arg = args[0].entity_type_id + mock_val = "entity_type_id_value" + assert arg == mock_val def test_create_entity_type_flattened_error(): @@ -2025,6 +2075,7 @@ def test_create_entity_type_flattened_error(): featurestore_service.CreateEntityTypeRequest(), parent="parent_value", entity_type=gca_entity_type.EntityType(name="name_value"), + entity_type_id="entity_type_id_value", ) @@ -2049,14 +2100,22 @@ async def test_create_entity_type_flattened_async(): response = await client.create_entity_type( parent="parent_value", entity_type=gca_entity_type.EntityType(name="name_value"), + entity_type_id="entity_type_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] - assert args[0].parent == "parent_value" - assert args[0].entity_type == gca_entity_type.EntityType(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].entity_type + mock_val = gca_entity_type.EntityType(name="name_value") + assert arg == mock_val + arg = args[0].entity_type_id + mock_val = "entity_type_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2072,6 +2131,7 @@ async def test_create_entity_type_flattened_error_async(): featurestore_service.CreateEntityTypeRequest(), parent="parent_value", entity_type=gca_entity_type.EntityType(name="name_value"), + entity_type_id="entity_type_id_value", ) @@ -2237,7 +2297,9 @@ def test_get_entity_type_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_entity_type_flattened_error(): @@ -2275,7 +2337,9 @@ async def test_get_entity_type_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2462,7 +2526,9 @@ def test_list_entity_types_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_entity_types_flattened_error(): @@ -2502,7 +2568,9 @@ async def test_list_entity_types_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2858,8 +2926,12 @@ def test_update_entity_type_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == gca_entity_type.EntityType(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].entity_type + mock_val = gca_entity_type.EntityType(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_entity_type_flattened_error(): @@ -2904,8 +2976,12 @@ async def test_update_entity_type_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == gca_entity_type.EntityType(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].entity_type + mock_val = gca_entity_type.EntityType(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 @@ -3090,8 +3166,12 @@ def test_delete_entity_type_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].force == True + 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_entity_type_flattened_error(): @@ -3133,8 +3213,12 @@ async def test_delete_entity_type_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].force == True + 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 @@ -3300,15 +3384,24 @@ def test_create_feature_flattened(): # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.create_feature( - parent="parent_value", feature=gca_feature.Feature(name="name_value"), + parent="parent_value", + feature=gca_feature.Feature(name="name_value"), + feature_id="feature_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] - assert args[0].parent == "parent_value" - assert args[0].feature == gca_feature.Feature(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].feature + mock_val = gca_feature.Feature(name="name_value") + assert arg == mock_val + arg = args[0].feature_id + mock_val = "feature_id_value" + assert arg == mock_val def test_create_feature_flattened_error(): @@ -3323,6 +3416,7 @@ def test_create_feature_flattened_error(): featurestore_service.CreateFeatureRequest(), parent="parent_value", feature=gca_feature.Feature(name="name_value"), + feature_id="feature_id_value", ) @@ -3343,15 +3437,24 @@ async def test_create_feature_flattened_async(): # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. response = await client.create_feature( - parent="parent_value", feature=gca_feature.Feature(name="name_value"), + parent="parent_value", + feature=gca_feature.Feature(name="name_value"), + feature_id="feature_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] - assert args[0].parent == "parent_value" - assert args[0].feature == gca_feature.Feature(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].feature + mock_val = gca_feature.Feature(name="name_value") + assert arg == mock_val + arg = args[0].feature_id + mock_val = "feature_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3367,6 +3470,7 @@ async def test_create_feature_flattened_error_async(): featurestore_service.CreateFeatureRequest(), parent="parent_value", feature=gca_feature.Feature(name="name_value"), + feature_id="feature_id_value", ) @@ -3538,10 +3642,12 @@ def test_batch_create_features_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].requests == [ - featurestore_service.CreateFeatureRequest(parent="parent_value") - ] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [featurestore_service.CreateFeatureRequest(parent="parent_value")] + assert arg == mock_val def test_batch_create_features_flattened_error(): @@ -3586,10 +3692,12 @@ async def test_batch_create_features_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].requests == [ - featurestore_service.CreateFeatureRequest(parent="parent_value") - ] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [featurestore_service.CreateFeatureRequest(parent="parent_value")] + assert arg == mock_val @pytest.mark.asyncio @@ -3775,7 +3883,9 @@ def test_get_feature_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_feature_flattened_error(): @@ -3811,7 +3921,9 @@ async def test_get_feature_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3986,7 +4098,9 @@ def test_list_features_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_features_flattened_error(): @@ -4024,7 +4138,9 @@ async def test_list_features_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4350,8 +4466,12 @@ def test_update_feature_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].feature == gca_feature.Feature(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].feature + mock_val = gca_feature.Feature(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_feature_flattened_error(): @@ -4392,8 +4512,12 @@ async def test_update_feature_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].feature == gca_feature.Feature(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].feature + mock_val = gca_feature.Feature(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 @@ -4564,7 +4688,9 @@ def test_delete_feature_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_feature_flattened_error(): @@ -4602,7 +4728,9 @@ async def test_delete_feature_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4784,7 +4912,9 @@ def test_import_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val def test_import_feature_values_flattened_error(): @@ -4825,7 +4955,9 @@ async def test_import_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5012,7 +5144,9 @@ def test_batch_read_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].featurestore == "featurestore_value" + arg = args[0].featurestore + mock_val = "featurestore_value" + assert arg == mock_val def test_batch_read_feature_values_flattened_error(): @@ -5055,7 +5189,9 @@ async def test_batch_read_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].featurestore == "featurestore_value" + arg = args[0].featurestore + mock_val = "featurestore_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5238,7 +5374,9 @@ def test_export_feature_values_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val def test_export_feature_values_flattened_error(): @@ -5279,7 +5417,9 @@ async def test_export_feature_values_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].entity_type == "entity_type_value" + arg = args[0].entity_type + mock_val = "entity_type_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5457,8 +5597,12 @@ def test_search_features_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].location == "location_value" - assert args[0].query == "query_value" + arg = args[0].location + mock_val = "location_value" + assert arg == mock_val + arg = args[0].query + mock_val = "query_value" + assert arg == mock_val def test_search_features_flattened_error(): @@ -5500,8 +5644,12 @@ async def test_search_features_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].location == "location_value" - assert args[0].query == "query_value" + arg = args[0].location + mock_val = "location_value" + assert arg == mock_val + arg = args[0].query + mock_val = "query_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_index_endpoint_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_index_endpoint_service.py index 00778abe49..9e96140fe4 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_index_endpoint_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_index_endpoint_service.py @@ -682,10 +682,12 @@ def test_create_index_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].index_endpoint == gca_index_endpoint.IndexEndpoint( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].index_endpoint + mock_val = gca_index_endpoint.IndexEndpoint(name="name_value") + assert arg == mock_val def test_create_index_endpoint_flattened_error(): @@ -730,10 +732,12 @@ async def test_create_index_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].index_endpoint == gca_index_endpoint.IndexEndpoint( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].index_endpoint + mock_val = gca_index_endpoint.IndexEndpoint(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -774,6 +778,7 @@ def test_get_index_endpoint( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, ) response = client.get_index_endpoint(request) @@ -789,6 +794,7 @@ def test_get_index_endpoint( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True def test_get_index_endpoint_from_dict(): @@ -837,6 +843,7 @@ async def test_get_index_endpoint_async( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, ) ) response = await client.get_index_endpoint(request) @@ -853,6 +860,7 @@ async def test_get_index_endpoint_async( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True @pytest.mark.asyncio @@ -938,7 +946,9 @@ def test_get_index_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_index_endpoint_flattened_error(): @@ -978,7 +988,9 @@ async def test_get_index_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1166,7 +1178,9 @@ def test_list_index_endpoints_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_index_endpoints_flattened_error(): @@ -1206,7 +1220,9 @@ async def test_list_index_endpoints_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1424,6 +1440,7 @@ def test_update_index_endpoint( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, ) response = client.update_index_endpoint(request) @@ -1439,6 +1456,7 @@ def test_update_index_endpoint( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True def test_update_index_endpoint_from_dict(): @@ -1487,6 +1505,7 @@ async def test_update_index_endpoint_async( description="description_value", etag="etag_value", network="network_value", + enable_private_service_connect=True, ) ) response = await client.update_index_endpoint(request) @@ -1503,6 +1522,7 @@ async def test_update_index_endpoint_async( assert response.description == "description_value" assert response.etag == "etag_value" assert response.network == "network_value" + assert response.enable_private_service_connect is True @pytest.mark.asyncio @@ -1597,10 +1617,12 @@ def test_update_index_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == gca_index_endpoint.IndexEndpoint( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].index_endpoint + mock_val = gca_index_endpoint.IndexEndpoint(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_index_endpoint_flattened_error(): @@ -1645,10 +1667,12 @@ async def test_update_index_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == gca_index_endpoint.IndexEndpoint( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].index_endpoint + mock_val = gca_index_endpoint.IndexEndpoint(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 @@ -1832,7 +1856,9 @@ def test_delete_index_endpoint_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_index_endpoint_flattened_error(): @@ -1872,7 +1898,9 @@ async def test_delete_index_endpoint_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2048,8 +2076,12 @@ def test_deploy_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == "index_endpoint_value" - assert args[0].deployed_index == gca_index_endpoint.DeployedIndex(id="id_value") + arg = args[0].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index + mock_val = gca_index_endpoint.DeployedIndex(id="id_value") + assert arg == mock_val def test_deploy_index_flattened_error(): @@ -2092,8 +2124,12 @@ async def test_deploy_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == "index_endpoint_value" - assert args[0].deployed_index == gca_index_endpoint.DeployedIndex(id="id_value") + arg = args[0].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index + mock_val = gca_index_endpoint.DeployedIndex(id="id_value") + assert arg == mock_val @pytest.mark.asyncio @@ -2271,8 +2307,12 @@ def test_undeploy_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == "index_endpoint_value" - assert args[0].deployed_index_id == "deployed_index_id_value" + arg = args[0].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index_id + mock_val = "deployed_index_id_value" + assert arg == mock_val def test_undeploy_index_flattened_error(): @@ -2315,8 +2355,12 @@ async def test_undeploy_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].index_endpoint == "index_endpoint_value" - assert args[0].deployed_index_id == "deployed_index_id_value" + arg = args[0].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index_id + mock_val = "deployed_index_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2335,6 +2379,252 @@ async def test_undeploy_index_flattened_error_async(): ) +def test_mutate_deployed_index( + transport: str = "grpc", + request_type=index_endpoint_service.MutateDeployedIndexRequest, +): + client = IndexEndpointServiceClient( + 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.mutate_deployed_index), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.mutate_deployed_index(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == index_endpoint_service.MutateDeployedIndexRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_mutate_deployed_index_from_dict(): + test_mutate_deployed_index(request_type=dict) + + +def test_mutate_deployed_index_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = IndexEndpointServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__call__" + ) as call: + client.mutate_deployed_index() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == index_endpoint_service.MutateDeployedIndexRequest() + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_async( + transport: str = "grpc_asyncio", + request_type=index_endpoint_service.MutateDeployedIndexRequest, +): + client = IndexEndpointServiceAsyncClient( + 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.mutate_deployed_index), "__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.mutate_deployed_index(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == index_endpoint_service.MutateDeployedIndexRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_async_from_dict(): + await test_mutate_deployed_index_async(request_type=dict) + + +def test_mutate_deployed_index_field_headers(): + client = IndexEndpointServiceClient( + 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 = index_endpoint_service.MutateDeployedIndexRequest() + + request.index_endpoint = "index_endpoint/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.mutate_deployed_index(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", "index_endpoint=index_endpoint/value",) in kw[ + "metadata" + ] + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_field_headers_async(): + client = IndexEndpointServiceAsyncClient( + 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 = index_endpoint_service.MutateDeployedIndexRequest() + + request.index_endpoint = "index_endpoint/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.mutate_deployed_index(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", "index_endpoint=index_endpoint/value",) in kw[ + "metadata" + ] + + +def test_mutate_deployed_index_flattened(): + client = IndexEndpointServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__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.mutate_deployed_index( + index_endpoint="index_endpoint_value", + deployed_index=gca_index_endpoint.DeployedIndex(id="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].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index + mock_val = gca_index_endpoint.DeployedIndex(id="id_value") + assert arg == mock_val + + +def test_mutate_deployed_index_flattened_error(): + client = IndexEndpointServiceClient( + 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.mutate_deployed_index( + index_endpoint_service.MutateDeployedIndexRequest(), + index_endpoint="index_endpoint_value", + deployed_index=gca_index_endpoint.DeployedIndex(id="id_value"), + ) + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_flattened_async(): + client = IndexEndpointServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.mutate_deployed_index), "__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.mutate_deployed_index( + index_endpoint="index_endpoint_value", + deployed_index=gca_index_endpoint.DeployedIndex(id="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].index_endpoint + mock_val = "index_endpoint_value" + assert arg == mock_val + arg = args[0].deployed_index + mock_val = gca_index_endpoint.DeployedIndex(id="id_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_mutate_deployed_index_flattened_error_async(): + client = IndexEndpointServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.mutate_deployed_index( + index_endpoint_service.MutateDeployedIndexRequest(), + index_endpoint="index_endpoint_value", + deployed_index=gca_index_endpoint.DeployedIndex(id="id_value"), + ) + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.IndexEndpointServiceGrpcTransport( @@ -2441,6 +2731,7 @@ def test_index_endpoint_service_base_transport(): "delete_index_endpoint", "deploy_index", "undeploy_index", + "mutate_deployed_index", ) for method in methods: with pytest.raises(NotImplementedError): diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_index_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_index_service.py index 58841ac68d..f54ca8e4ca 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_index_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_index_service.py @@ -624,8 +624,12 @@ def test_create_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].index == gca_index.Index(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].index + mock_val = gca_index.Index(name="name_value") + assert arg == mock_val def test_create_index_flattened_error(): @@ -663,8 +667,12 @@ async def test_create_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].index == gca_index.Index(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].index + mock_val = gca_index.Index(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -844,7 +852,9 @@ def test_get_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_index_flattened_error(): @@ -876,7 +886,9 @@ async def test_get_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1040,7 +1052,9 @@ def test_list_indexes_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_indexes_flattened_error(): @@ -1074,7 +1088,9 @@ async def test_list_indexes_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1351,8 +1367,12 @@ def test_update_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].index == gca_index.Index(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].index + mock_val = gca_index.Index(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_index_flattened_error(): @@ -1391,8 +1411,12 @@ async def test_update_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].index == gca_index.Index(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].index + mock_val = gca_index.Index(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 @@ -1554,7 +1578,9 @@ def test_delete_index_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_index_flattened_error(): @@ -1588,7 +1614,9 @@ async def test_delete_index_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_job_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_job_service.py index b97cd745ed..4538fb5fbe 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_job_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_job_service.py @@ -51,6 +51,7 @@ data_labeling_job as gca_data_labeling_job, ) from google.cloud.aiplatform_v1beta1.types import encryption_spec +from google.cloud.aiplatform_v1beta1.types import env_var from google.cloud.aiplatform_v1beta1.types import explanation from google.cloud.aiplatform_v1beta1.types import explanation_metadata from google.cloud.aiplatform_v1beta1.types import hyperparameter_tuning_job @@ -62,6 +63,7 @@ from google.cloud.aiplatform_v1beta1.types import job_state from google.cloud.aiplatform_v1beta1.types import machine_resources from google.cloud.aiplatform_v1beta1.types import manual_batch_tuning_parameters +from google.cloud.aiplatform_v1beta1.types import model from google.cloud.aiplatform_v1beta1.types import model_deployment_monitoring_job from google.cloud.aiplatform_v1beta1.types import ( model_deployment_monitoring_job as gca_model_deployment_monitoring_job, @@ -69,6 +71,7 @@ from google.cloud.aiplatform_v1beta1.types import model_monitoring from google.cloud.aiplatform_v1beta1.types import operation as gca_operation from google.cloud.aiplatform_v1beta1.types import study +from google.cloud.aiplatform_v1beta1.types import unmanaged_container_model from google.longrunning import operations_pb2 from google.oauth2 import service_account from google.protobuf import any_pb2 # type: ignore @@ -679,8 +682,12 @@ def test_create_custom_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].custom_job == gca_custom_job.CustomJob(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].custom_job + mock_val = gca_custom_job.CustomJob(name="name_value") + assert arg == mock_val def test_create_custom_job_flattened_error(): @@ -721,8 +728,12 @@ async def test_create_custom_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].custom_job == gca_custom_job.CustomJob(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].custom_job + mock_val = gca_custom_job.CustomJob(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -898,7 +909,9 @@ def test_get_custom_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_custom_job_flattened_error(): @@ -932,7 +945,9 @@ async def test_get_custom_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1096,7 +1111,9 @@ def test_list_custom_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_custom_jobs_flattened_error(): @@ -1130,7 +1147,9 @@ async def test_list_custom_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1440,7 +1459,9 @@ def test_delete_custom_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_custom_job_flattened_error(): @@ -1476,7 +1497,9 @@ async def test_delete_custom_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1644,7 +1667,9 @@ def test_cancel_custom_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_custom_job_flattened_error(): @@ -1678,7 +1703,9 @@ async def test_cancel_custom_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1892,10 +1919,12 @@ def test_create_data_labeling_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].data_labeling_job == gca_data_labeling_job.DataLabelingJob( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].data_labeling_job + mock_val = gca_data_labeling_job.DataLabelingJob(name="name_value") + assert arg == mock_val def test_create_data_labeling_job_flattened_error(): @@ -1936,10 +1965,12 @@ async def test_create_data_labeling_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].data_labeling_job == gca_data_labeling_job.DataLabelingJob( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].data_labeling_job + mock_val = gca_data_labeling_job.DataLabelingJob(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -2151,7 +2182,9 @@ def test_get_data_labeling_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_data_labeling_job_flattened_error(): @@ -2187,7 +2220,9 @@ async def test_get_data_labeling_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2366,7 +2401,9 @@ def test_list_data_labeling_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_data_labeling_jobs_flattened_error(): @@ -2402,7 +2439,9 @@ async def test_list_data_labeling_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2745,7 +2784,9 @@ def test_delete_data_labeling_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_data_labeling_job_flattened_error(): @@ -2781,7 +2822,9 @@ async def test_delete_data_labeling_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2950,7 +2993,9 @@ def test_cancel_data_labeling_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_data_labeling_job_flattened_error(): @@ -2984,7 +3029,9 @@ async def test_cancel_data_labeling_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3189,12 +3236,14 @@ def test_create_hyperparameter_tuning_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].hyperparameter_tuning_job == gca_hyperparameter_tuning_job.HyperparameterTuningJob( + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].hyperparameter_tuning_job + mock_val = gca_hyperparameter_tuning_job.HyperparameterTuningJob( name="name_value" ) + assert arg == mock_val def test_create_hyperparameter_tuning_job_flattened_error(): @@ -3239,12 +3288,14 @@ async def test_create_hyperparameter_tuning_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].hyperparameter_tuning_job == gca_hyperparameter_tuning_job.HyperparameterTuningJob( + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].hyperparameter_tuning_job + mock_val = gca_hyperparameter_tuning_job.HyperparameterTuningJob( name="name_value" ) + assert arg == mock_val @pytest.mark.asyncio @@ -3447,7 +3498,9 @@ def test_get_hyperparameter_tuning_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_hyperparameter_tuning_job_flattened_error(): @@ -3483,7 +3536,9 @@ async def test_get_hyperparameter_tuning_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3663,7 +3718,9 @@ def test_list_hyperparameter_tuning_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_hyperparameter_tuning_jobs_flattened_error(): @@ -3699,7 +3756,9 @@ async def test_list_hyperparameter_tuning_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4059,7 +4118,9 @@ def test_delete_hyperparameter_tuning_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_hyperparameter_tuning_job_flattened_error(): @@ -4095,7 +4156,9 @@ async def test_delete_hyperparameter_tuning_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4265,7 +4328,9 @@ def test_cancel_hyperparameter_tuning_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_hyperparameter_tuning_job_flattened_error(): @@ -4299,7 +4364,9 @@ async def test_cancel_hyperparameter_tuning_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4499,12 +4566,12 @@ def test_create_batch_prediction_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].batch_prediction_job == gca_batch_prediction_job.BatchPredictionJob( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].batch_prediction_job + mock_val = gca_batch_prediction_job.BatchPredictionJob(name="name_value") + assert arg == mock_val def test_create_batch_prediction_job_flattened_error(): @@ -4549,12 +4616,12 @@ async def test_create_batch_prediction_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].batch_prediction_job == gca_batch_prediction_job.BatchPredictionJob( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].batch_prediction_job + mock_val = gca_batch_prediction_job.BatchPredictionJob(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -4753,7 +4820,9 @@ def test_get_batch_prediction_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_batch_prediction_job_flattened_error(): @@ -4789,7 +4858,9 @@ async def test_get_batch_prediction_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4968,7 +5039,9 @@ def test_list_batch_prediction_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_batch_prediction_jobs_flattened_error(): @@ -5004,7 +5077,9 @@ async def test_list_batch_prediction_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5351,7 +5426,9 @@ def test_delete_batch_prediction_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_batch_prediction_job_flattened_error(): @@ -5387,7 +5464,9 @@ async def test_delete_batch_prediction_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5556,7 +5635,9 @@ def test_cancel_batch_prediction_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_batch_prediction_job_flattened_error(): @@ -5590,7 +5671,9 @@ async def test_cancel_batch_prediction_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5817,12 +5900,14 @@ def test_create_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].model_deployment_monitoring_job == gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model_deployment_monitoring_job + mock_val = gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( name="name_value" ) + assert arg == mock_val def test_create_model_deployment_monitoring_job_flattened_error(): @@ -5869,12 +5954,14 @@ async def test_create_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].model_deployment_monitoring_job == gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model_deployment_monitoring_job + mock_val = gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( name="name_value" ) + assert arg == mock_val @pytest.mark.asyncio @@ -6094,11 +6181,12 @@ def test_search_model_deployment_monitoring_stats_anomalies_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert ( - args[0].model_deployment_monitoring_job - == "model_deployment_monitoring_job_value" - ) - assert args[0].deployed_model_id == "deployed_model_id_value" + arg = args[0].model_deployment_monitoring_job + mock_val = "model_deployment_monitoring_job_value" + assert arg == mock_val + arg = args[0].deployed_model_id + mock_val = "deployed_model_id_value" + assert arg == mock_val def test_search_model_deployment_monitoring_stats_anomalies_flattened_error(): @@ -6142,11 +6230,12 @@ async def test_search_model_deployment_monitoring_stats_anomalies_flattened_asyn # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert ( - args[0].model_deployment_monitoring_job - == "model_deployment_monitoring_job_value" - ) - assert args[0].deployed_model_id == "deployed_model_id_value" + arg = args[0].model_deployment_monitoring_job + mock_val = "model_deployment_monitoring_job_value" + assert arg == mock_val + arg = args[0].deployed_model_id + mock_val = "deployed_model_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6568,7 +6657,9 @@ def test_get_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_model_deployment_monitoring_job_flattened_error(): @@ -6606,7 +6697,9 @@ async def test_get_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6786,7 +6879,9 @@ def test_list_model_deployment_monitoring_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_model_deployment_monitoring_jobs_flattened_error(): @@ -6825,7 +6920,9 @@ async def test_list_model_deployment_monitoring_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7201,12 +7298,14 @@ def test_update_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[ - 0 - ].model_deployment_monitoring_job == gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( + arg = args[0].model_deployment_monitoring_job + mock_val = gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( name="name_value" ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val def test_update_model_deployment_monitoring_job_flattened_error(): @@ -7251,12 +7350,14 @@ async def test_update_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[ - 0 - ].model_deployment_monitoring_job == gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( + arg = args[0].model_deployment_monitoring_job + mock_val = gca_model_deployment_monitoring_job.ModelDeploymentMonitoringJob( name="name_value" ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_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 @@ -7434,7 +7535,9 @@ def test_delete_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_model_deployment_monitoring_job_flattened_error(): @@ -7472,7 +7575,9 @@ async def test_delete_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7642,7 +7747,9 @@ def test_pause_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_pause_model_deployment_monitoring_job_flattened_error(): @@ -7678,7 +7785,9 @@ async def test_pause_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7848,7 +7957,9 @@ def test_resume_model_deployment_monitoring_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_resume_model_deployment_monitoring_job_flattened_error(): @@ -7884,7 +7995,9 @@ async def test_resume_model_deployment_monitoring_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_metadata_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_metadata_service.py index 9fd9f75d62..1407bbd817 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_metadata_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_metadata_service.py @@ -676,11 +676,15 @@ def test_create_metadata_store_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].metadata_store == gca_metadata_store.MetadataStore( - name="name_value" - ) - assert args[0].metadata_store_id == "metadata_store_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].metadata_store + mock_val = gca_metadata_store.MetadataStore(name="name_value") + assert arg == mock_val + arg = args[0].metadata_store_id + mock_val = "metadata_store_id_value" + assert arg == mock_val def test_create_metadata_store_flattened_error(): @@ -725,11 +729,15 @@ async def test_create_metadata_store_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].metadata_store == gca_metadata_store.MetadataStore( - name="name_value" - ) - assert args[0].metadata_store_id == "metadata_store_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].metadata_store + mock_val = gca_metadata_store.MetadataStore(name="name_value") + assert arg == mock_val + arg = args[0].metadata_store_id + mock_val = "metadata_store_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -917,7 +925,9 @@ def test_get_metadata_store_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_metadata_store_flattened_error(): @@ -955,7 +965,9 @@ async def test_get_metadata_store_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1138,7 +1150,9 @@ def test_list_metadata_stores_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_metadata_stores_flattened_error(): @@ -1176,7 +1190,9 @@ async def test_list_metadata_stores_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1527,7 +1543,9 @@ def test_delete_metadata_store_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_metadata_store_flattened_error(): @@ -1565,7 +1583,9 @@ async def test_delete_metadata_store_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1767,9 +1787,15 @@ def test_create_artifact_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].artifact == gca_artifact.Artifact(name="name_value") - assert args[0].artifact_id == "artifact_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].artifact + mock_val = gca_artifact.Artifact(name="name_value") + assert arg == mock_val + arg = args[0].artifact_id + mock_val = "artifact_id_value" + assert arg == mock_val def test_create_artifact_flattened_error(): @@ -1812,9 +1838,15 @@ async def test_create_artifact_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].artifact == gca_artifact.Artifact(name="name_value") - assert args[0].artifact_id == "artifact_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].artifact + mock_val = gca_artifact.Artifact(name="name_value") + assert arg == mock_val + arg = args[0].artifact_id + mock_val = "artifact_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2013,7 +2045,9 @@ def test_get_artifact_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_artifact_flattened_error(): @@ -2047,7 +2081,9 @@ async def test_get_artifact_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2217,7 +2253,9 @@ def test_list_artifacts_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_artifacts_flattened_error(): @@ -2253,7 +2291,9 @@ async def test_list_artifacts_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2608,8 +2648,12 @@ def test_update_artifact_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].artifact == gca_artifact.Artifact(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].artifact + mock_val = gca_artifact.Artifact(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_artifact_flattened_error(): @@ -2650,8 +2694,12 @@ async def test_update_artifact_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].artifact == gca_artifact.Artifact(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].artifact + mock_val = gca_artifact.Artifact(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 @@ -2817,7 +2865,9 @@ def test_delete_artifact_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_artifact_flattened_error(): @@ -2853,7 +2903,9 @@ async def test_delete_artifact_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3017,7 +3069,9 @@ def test_purge_artifacts_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_purge_artifacts_flattened_error(): @@ -3053,7 +3107,9 @@ async def test_purge_artifacts_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3249,9 +3305,15 @@ def test_create_context_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].context == gca_context.Context(name="name_value") - assert args[0].context_id == "context_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].context + mock_val = gca_context.Context(name="name_value") + assert arg == mock_val + arg = args[0].context_id + mock_val = "context_id_value" + assert arg == mock_val def test_create_context_flattened_error(): @@ -3292,9 +3354,15 @@ async def test_create_context_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].context == gca_context.Context(name="name_value") - assert args[0].context_id == "context_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].context + mock_val = gca_context.Context(name="name_value") + assert arg == mock_val + arg = args[0].context_id + mock_val = "context_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3489,7 +3557,9 @@ def test_get_context_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_context_flattened_error(): @@ -3523,7 +3593,9 @@ async def test_get_context_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3693,7 +3765,9 @@ def test_list_contexts_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_contexts_flattened_error(): @@ -3729,7 +3803,9 @@ async def test_list_contexts_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4054,8 +4130,12 @@ def test_update_context_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].context == gca_context.Context(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].context + mock_val = gca_context.Context(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_context_flattened_error(): @@ -4094,8 +4174,12 @@ async def test_update_context_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].context == gca_context.Context(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].context + mock_val = gca_context.Context(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 @@ -4261,7 +4345,9 @@ def test_delete_context_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_context_flattened_error(): @@ -4297,7 +4383,9 @@ async def test_delete_context_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4461,7 +4549,9 @@ def test_purge_contexts_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_purge_contexts_flattened_error(): @@ -4497,7 +4587,9 @@ async def test_purge_contexts_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4683,9 +4775,15 @@ def test_add_context_artifacts_and_executions_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" - assert args[0].artifacts == ["artifacts_value"] - assert args[0].executions == ["executions_value"] + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val + arg = args[0].artifacts + mock_val = ["artifacts_value"] + assert arg == mock_val + arg = args[0].executions + mock_val = ["executions_value"] + assert arg == mock_val def test_add_context_artifacts_and_executions_flattened_error(): @@ -4730,9 +4828,15 @@ async def test_add_context_artifacts_and_executions_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" - assert args[0].artifacts == ["artifacts_value"] - assert args[0].executions == ["executions_value"] + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val + arg = args[0].artifacts + mock_val = ["artifacts_value"] + assert arg == mock_val + arg = args[0].executions + mock_val = ["executions_value"] + assert arg == mock_val @pytest.mark.asyncio @@ -4914,8 +5018,12 @@ def test_add_context_children_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" - assert args[0].child_contexts == ["child_contexts_value"] + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val + arg = args[0].child_contexts + mock_val = ["child_contexts_value"] + assert arg == mock_val def test_add_context_children_flattened_error(): @@ -4957,8 +5065,12 @@ async def test_add_context_children_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" - assert args[0].child_contexts == ["child_contexts_value"] + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val + arg = args[0].child_contexts + mock_val = ["child_contexts_value"] + assert arg == mock_val @pytest.mark.asyncio @@ -5138,7 +5250,9 @@ def test_query_context_lineage_subgraph_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val def test_query_context_lineage_subgraph_flattened_error(): @@ -5177,7 +5291,9 @@ async def test_query_context_lineage_subgraph_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].context == "context_value" + arg = args[0].context + mock_val = "context_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5377,9 +5493,15 @@ def test_create_execution_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].execution == gca_execution.Execution(name="name_value") - assert args[0].execution_id == "execution_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].execution + mock_val = gca_execution.Execution(name="name_value") + assert arg == mock_val + arg = args[0].execution_id + mock_val = "execution_id_value" + assert arg == mock_val def test_create_execution_flattened_error(): @@ -5422,9 +5544,15 @@ async def test_create_execution_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].execution == gca_execution.Execution(name="name_value") - assert args[0].execution_id == "execution_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].execution + mock_val = gca_execution.Execution(name="name_value") + assert arg == mock_val + arg = args[0].execution_id + mock_val = "execution_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5619,7 +5747,9 @@ def test_get_execution_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_execution_flattened_error(): @@ -5653,7 +5783,9 @@ async def test_get_execution_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5823,7 +5955,9 @@ def test_list_executions_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_executions_flattened_error(): @@ -5859,7 +5993,9 @@ async def test_list_executions_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6211,8 +6347,12 @@ def test_update_execution_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].execution == gca_execution.Execution(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].execution + mock_val = gca_execution.Execution(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_execution_flattened_error(): @@ -6253,8 +6393,12 @@ async def test_update_execution_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].execution == gca_execution.Execution(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].execution + mock_val = gca_execution.Execution(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 @@ -6421,7 +6565,9 @@ def test_delete_execution_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_execution_flattened_error(): @@ -6457,7 +6603,9 @@ async def test_delete_execution_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6622,7 +6770,9 @@ def test_purge_executions_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_purge_executions_flattened_error(): @@ -6658,7 +6808,9 @@ async def test_purge_executions_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6838,8 +6990,12 @@ def test_add_execution_events_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].execution == "execution_value" - assert args[0].events == [event.Event(artifact="artifact_value")] + arg = args[0].execution + mock_val = "execution_value" + assert arg == mock_val + arg = args[0].events + mock_val = [event.Event(artifact="artifact_value")] + assert arg == mock_val def test_add_execution_events_flattened_error(): @@ -6882,8 +7038,12 @@ async def test_add_execution_events_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].execution == "execution_value" - assert args[0].events == [event.Event(artifact="artifact_value")] + arg = args[0].execution + mock_val = "execution_value" + assert arg == mock_val + arg = args[0].events + mock_val = [event.Event(artifact="artifact_value")] + assert arg == mock_val @pytest.mark.asyncio @@ -7063,7 +7223,9 @@ def test_query_execution_inputs_and_outputs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].execution == "execution_value" + arg = args[0].execution + mock_val = "execution_value" + assert arg == mock_val def test_query_execution_inputs_and_outputs_flattened_error(): @@ -7104,7 +7266,9 @@ async def test_query_execution_inputs_and_outputs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].execution == "execution_value" + arg = args[0].execution + mock_val = "execution_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7314,11 +7478,15 @@ def test_create_metadata_schema_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].metadata_schema == gca_metadata_schema.MetadataSchema( - name="name_value" - ) - assert args[0].metadata_schema_id == "metadata_schema_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].metadata_schema + mock_val = gca_metadata_schema.MetadataSchema(name="name_value") + assert arg == mock_val + arg = args[0].metadata_schema_id + mock_val = "metadata_schema_id_value" + assert arg == mock_val def test_create_metadata_schema_flattened_error(): @@ -7363,11 +7531,15 @@ async def test_create_metadata_schema_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].metadata_schema == gca_metadata_schema.MetadataSchema( - name="name_value" - ) - assert args[0].metadata_schema_id == "metadata_schema_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].metadata_schema + mock_val = gca_metadata_schema.MetadataSchema(name="name_value") + assert arg == mock_val + arg = args[0].metadata_schema_id + mock_val = "metadata_schema_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7575,7 +7747,9 @@ def test_get_metadata_schema_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_metadata_schema_flattened_error(): @@ -7613,7 +7787,9 @@ async def test_get_metadata_schema_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7796,7 +7972,9 @@ def test_list_metadata_schemas_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_metadata_schemas_flattened_error(): @@ -7834,7 +8012,9 @@ async def test_list_metadata_schemas_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -8186,7 +8366,9 @@ def test_query_artifact_lineage_subgraph_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].artifact == "artifact_value" + arg = args[0].artifact + mock_val = "artifact_value" + assert arg == mock_val def test_query_artifact_lineage_subgraph_flattened_error(): @@ -8227,7 +8409,9 @@ async def test_query_artifact_lineage_subgraph_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].artifact == "artifact_value" + arg = args[0].artifact + mock_val = "artifact_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_migration_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_migration_service.py index 6e864f2f4e..176dc81e61 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_migration_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_migration_service.py @@ -664,7 +664,9 @@ def test_search_migratable_resources_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_search_migratable_resources_flattened_error(): @@ -702,7 +704,9 @@ async def test_search_migratable_resources_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1066,14 +1070,18 @@ def test_batch_migrate_resources_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].migrate_resource_requests == [ + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].migrate_resource_requests + mock_val = [ migration_service.MigrateResourceRequest( migrate_ml_engine_model_version_config=migration_service.MigrateResourceRequest.MigrateMlEngineModelVersionConfig( endpoint="endpoint_value" ) ) ] + assert arg == mock_val def test_batch_migrate_resources_flattened_error(): @@ -1128,14 +1136,18 @@ async def test_batch_migrate_resources_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].migrate_resource_requests == [ + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].migrate_resource_requests + mock_val = [ migration_service.MigrateResourceRequest( migrate_ml_engine_model_version_config=migration_service.MigrateResourceRequest.MigrateMlEngineModelVersionConfig( endpoint="endpoint_value" ) ) ] + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_model_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_model_service.py index d620dbe483..31bb04d225 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_model_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_model_service.py @@ -631,8 +631,12 @@ def test_upload_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].model == gca_model.Model(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model + mock_val = gca_model.Model(name="name_value") + assert arg == mock_val def test_upload_model_flattened_error(): @@ -670,8 +674,12 @@ async def test_upload_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].model == gca_model.Model(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].model + mock_val = gca_model.Model(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -891,7 +899,9 @@ def test_get_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_model_flattened_error(): @@ -923,7 +933,9 @@ async def test_get_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1087,7 +1099,9 @@ def test_list_models_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_models_flattened_error(): @@ -1121,7 +1135,9 @@ async def test_list_models_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1458,8 +1474,12 @@ def test_update_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].model == gca_model.Model(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].model + mock_val = gca_model.Model(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val def test_update_model_flattened_error(): @@ -1496,8 +1516,12 @@ async def test_update_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].model == gca_model.Model(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].model + mock_val = gca_model.Model(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val @pytest.mark.asyncio @@ -1659,7 +1683,9 @@ def test_delete_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_model_flattened_error(): @@ -1693,7 +1719,9 @@ async def test_delete_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1858,10 +1886,14 @@ def test_export_model_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].output_config == model_service.ExportModelRequest.OutputConfig( + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].output_config + mock_val = model_service.ExportModelRequest.OutputConfig( export_format_id="export_format_id_value" ) + assert arg == mock_val def test_export_model_flattened_error(): @@ -1904,10 +1936,14 @@ async def test_export_model_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].output_config == model_service.ExportModelRequest.OutputConfig( + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].output_config + mock_val = model_service.ExportModelRequest.OutputConfig( export_format_id="export_format_id_value" ) + assert arg == mock_val @pytest.mark.asyncio @@ -2098,7 +2134,9 @@ def test_get_model_evaluation_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_model_evaluation_flattened_error(): @@ -2134,7 +2172,9 @@ async def test_get_model_evaluation_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2313,7 +2353,9 @@ def test_list_model_evaluations_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_model_evaluations_flattened_error(): @@ -2349,7 +2391,9 @@ async def test_list_model_evaluations_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2700,7 +2744,9 @@ def test_get_model_evaluation_slice_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_model_evaluation_slice_flattened_error(): @@ -2736,7 +2782,9 @@ async def test_get_model_evaluation_slice_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2915,7 +2963,9 @@ def test_list_model_evaluation_slices_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_model_evaluation_slices_flattened_error(): @@ -2951,7 +3001,9 @@ async def test_list_model_evaluation_slices_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_pipeline_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_pipeline_service.py index edb2e0b5a2..2f587a9d04 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_pipeline_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_pipeline_service.py @@ -700,10 +700,12 @@ def test_create_training_pipeline_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].training_pipeline == gca_training_pipeline.TrainingPipeline( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].training_pipeline + mock_val = gca_training_pipeline.TrainingPipeline(name="name_value") + assert arg == mock_val def test_create_training_pipeline_flattened_error(): @@ -746,10 +748,12 @@ async def test_create_training_pipeline_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].training_pipeline == gca_training_pipeline.TrainingPipeline( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].training_pipeline + mock_val = gca_training_pipeline.TrainingPipeline(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -946,7 +950,9 @@ def test_get_training_pipeline_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_training_pipeline_flattened_error(): @@ -984,7 +990,9 @@ async def test_get_training_pipeline_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1167,7 +1175,9 @@ def test_list_training_pipelines_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_training_pipelines_flattened_error(): @@ -1205,7 +1215,9 @@ async def test_list_training_pipelines_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1556,7 +1568,9 @@ def test_delete_training_pipeline_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_training_pipeline_flattened_error(): @@ -1594,7 +1608,9 @@ async def test_delete_training_pipeline_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1767,7 +1783,9 @@ def test_cancel_training_pipeline_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_training_pipeline_flattened_error(): @@ -1803,7 +1821,9 @@ async def test_cancel_training_pipeline_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2006,9 +2026,15 @@ def test_create_pipeline_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].pipeline_job == gca_pipeline_job.PipelineJob(name="name_value") - assert args[0].pipeline_job_id == "pipeline_job_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].pipeline_job + mock_val = gca_pipeline_job.PipelineJob(name="name_value") + assert arg == mock_val + arg = args[0].pipeline_job_id + mock_val = "pipeline_job_id_value" + assert arg == mock_val def test_create_pipeline_job_flattened_error(): @@ -2053,9 +2079,15 @@ async def test_create_pipeline_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].pipeline_job == gca_pipeline_job.PipelineJob(name="name_value") - assert args[0].pipeline_job_id == "pipeline_job_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].pipeline_job + mock_val = gca_pipeline_job.PipelineJob(name="name_value") + assert arg == mock_val + arg = args[0].pipeline_job_id + mock_val = "pipeline_job_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2244,7 +2276,9 @@ def test_get_pipeline_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_pipeline_job_flattened_error(): @@ -2280,7 +2314,9 @@ async def test_get_pipeline_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2463,7 +2499,9 @@ def test_list_pipeline_jobs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_pipeline_jobs_flattened_error(): @@ -2501,7 +2539,9 @@ async def test_list_pipeline_jobs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2836,7 +2876,9 @@ def test_delete_pipeline_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_pipeline_job_flattened_error(): @@ -2874,7 +2916,9 @@ async def test_delete_pipeline_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3047,7 +3091,9 @@ def test_cancel_pipeline_job_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_cancel_pipeline_job_flattened_error(): @@ -3083,7 +3129,9 @@ async def test_cancel_pipeline_job_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_prediction_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_prediction_service.py index 89ce1a9cb1..aa0f4c76b5 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_prediction_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_prediction_service.py @@ -829,10 +829,12 @@ def test_raw_predict_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].http_body == httpbody_pb2.HttpBody( - content_type="content_type_value" - ) + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].http_body + mock_val = httpbody_pb2.HttpBody(content_type="content_type_value") + assert arg == mock_val def test_raw_predict_flattened_error(): @@ -873,10 +875,12 @@ async def test_raw_predict_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].endpoint == "endpoint_value" - assert args[0].http_body == httpbody_pb2.HttpBody( - content_type="content_type_value" - ) + arg = args[0].endpoint + mock_val = "endpoint_value" + assert arg == mock_val + arg = args[0].http_body + mock_val = httpbody_pb2.HttpBody(content_type="content_type_value") + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_specialist_pool_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_specialist_pool_service.py index fca244846d..490e6d5f97 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_specialist_pool_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_specialist_pool_service.py @@ -680,10 +680,12 @@ def test_create_specialist_pool_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].specialist_pool == gca_specialist_pool.SpecialistPool( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].specialist_pool + mock_val = gca_specialist_pool.SpecialistPool(name="name_value") + assert arg == mock_val def test_create_specialist_pool_flattened_error(): @@ -728,10 +730,12 @@ async def test_create_specialist_pool_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].specialist_pool == gca_specialist_pool.SpecialistPool( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].specialist_pool + mock_val = gca_specialist_pool.SpecialistPool(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -941,7 +945,9 @@ def test_get_specialist_pool_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_specialist_pool_flattened_error(): @@ -981,7 +987,9 @@ async def test_get_specialist_pool_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1169,7 +1177,9 @@ def test_list_specialist_pools_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_specialist_pools_flattened_error(): @@ -1209,7 +1219,9 @@ async def test_list_specialist_pools_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1569,7 +1581,9 @@ def test_delete_specialist_pool_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_specialist_pool_flattened_error(): @@ -1609,7 +1623,9 @@ async def test_delete_specialist_pool_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1800,10 +1816,12 @@ def test_update_specialist_pool_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].specialist_pool == gca_specialist_pool.SpecialistPool( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].specialist_pool + mock_val = gca_specialist_pool.SpecialistPool(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_specialist_pool_flattened_error(): @@ -1848,10 +1866,12 @@ async def test_update_specialist_pool_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].specialist_pool == gca_specialist_pool.SpecialistPool( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].specialist_pool + mock_val = gca_specialist_pool.SpecialistPool(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 diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_tensorboard_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_tensorboard_service.py index de5a34fbec..332bf28c9a 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_tensorboard_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_tensorboard_service.py @@ -680,8 +680,12 @@ def test_create_tensorboard_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].tensorboard == gca_tensorboard.Tensorboard(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard + mock_val = gca_tensorboard.Tensorboard(name="name_value") + assert arg == mock_val def test_create_tensorboard_flattened_error(): @@ -726,8 +730,12 @@ async def test_create_tensorboard_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].tensorboard == gca_tensorboard.Tensorboard(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard + mock_val = gca_tensorboard.Tensorboard(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -924,7 +932,9 @@ def test_get_tensorboard_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_tensorboard_flattened_error(): @@ -962,7 +972,9 @@ async def test_get_tensorboard_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1150,8 +1162,12 @@ def test_update_tensorboard_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].tensorboard == gca_tensorboard.Tensorboard(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].tensorboard + mock_val = gca_tensorboard.Tensorboard(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_tensorboard_flattened_error(): @@ -1196,8 +1212,12 @@ async def test_update_tensorboard_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].tensorboard == gca_tensorboard.Tensorboard(name="name_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].tensorboard + mock_val = gca_tensorboard.Tensorboard(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 @@ -1386,7 +1406,9 @@ def test_list_tensorboards_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_tensorboards_flattened_error(): @@ -1426,7 +1448,9 @@ async def test_list_tensorboards_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1765,7 +1789,9 @@ def test_delete_tensorboard_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_tensorboard_flattened_error(): @@ -1805,7 +1831,9 @@ async def test_delete_tensorboard_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2015,13 +2043,15 @@ def test_create_tensorboard_experiment_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].tensorboard_experiment == gca_tensorboard_experiment.TensorboardExperiment( - name="name_value" - ) - assert args[0].tensorboard_experiment_id == "tensorboard_experiment_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard_experiment + mock_val = gca_tensorboard_experiment.TensorboardExperiment(name="name_value") + assert arg == mock_val + arg = args[0].tensorboard_experiment_id + mock_val = "tensorboard_experiment_id_value" + assert arg == mock_val def test_create_tensorboard_experiment_flattened_error(): @@ -2072,13 +2102,15 @@ async def test_create_tensorboard_experiment_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].tensorboard_experiment == gca_tensorboard_experiment.TensorboardExperiment( - name="name_value" - ) - assert args[0].tensorboard_experiment_id == "tensorboard_experiment_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard_experiment + mock_val = gca_tensorboard_experiment.TensorboardExperiment(name="name_value") + assert arg == mock_val + arg = args[0].tensorboard_experiment_id + mock_val = "tensorboard_experiment_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2287,7 +2319,9 @@ def test_get_tensorboard_experiment_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_tensorboard_experiment_flattened_error(): @@ -2327,7 +2361,9 @@ async def test_get_tensorboard_experiment_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2542,12 +2578,12 @@ def test_update_tensorboard_experiment_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[ - 0 - ].tensorboard_experiment == gca_tensorboard_experiment.TensorboardExperiment( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].tensorboard_experiment + mock_val = gca_tensorboard_experiment.TensorboardExperiment(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_tensorboard_experiment_flattened_error(): @@ -2596,12 +2632,12 @@ async def test_update_tensorboard_experiment_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[ - 0 - ].tensorboard_experiment == gca_tensorboard_experiment.TensorboardExperiment( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].tensorboard_experiment + mock_val = gca_tensorboard_experiment.TensorboardExperiment(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 @@ -2793,7 +2829,9 @@ def test_list_tensorboard_experiments_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_tensorboard_experiments_flattened_error(): @@ -2834,7 +2872,9 @@ async def test_list_tensorboard_experiments_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3206,7 +3246,9 @@ def test_delete_tensorboard_experiment_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_tensorboard_experiment_flattened_error(): @@ -3246,7 +3288,9 @@ async def test_delete_tensorboard_experiment_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3450,11 +3494,15 @@ def test_create_tensorboard_run_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].tensorboard_run == gca_tensorboard_run.TensorboardRun( - name="name_value" - ) - assert args[0].tensorboard_run_id == "tensorboard_run_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard_run + mock_val = gca_tensorboard_run.TensorboardRun(name="name_value") + assert arg == mock_val + arg = args[0].tensorboard_run_id + mock_val = "tensorboard_run_id_value" + assert arg == mock_val def test_create_tensorboard_run_flattened_error(): @@ -3501,11 +3549,15 @@ async def test_create_tensorboard_run_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].tensorboard_run == gca_tensorboard_run.TensorboardRun( - name="name_value" - ) - assert args[0].tensorboard_run_id == "tensorboard_run_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard_run + mock_val = gca_tensorboard_run.TensorboardRun(name="name_value") + assert arg == mock_val + arg = args[0].tensorboard_run_id + mock_val = "tensorboard_run_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3695,10 +3747,14 @@ def test_batch_create_tensorboard_runs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].requests == [ + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [ tensorboard_service.CreateTensorboardRunRequest(parent="parent_value") ] + assert arg == mock_val def test_batch_create_tensorboard_runs_flattened_error(): @@ -3747,10 +3803,14 @@ async def test_batch_create_tensorboard_runs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].requests == [ + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [ tensorboard_service.CreateTensorboardRunRequest(parent="parent_value") ] + assert arg == mock_val @pytest.mark.asyncio @@ -3953,7 +4013,9 @@ def test_get_tensorboard_run_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_tensorboard_run_flattened_error(): @@ -3993,7 +4055,9 @@ async def test_get_tensorboard_run_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4202,10 +4266,12 @@ def test_update_tensorboard_run_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_run == gca_tensorboard_run.TensorboardRun( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].tensorboard_run + mock_val = gca_tensorboard_run.TensorboardRun(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_tensorboard_run_flattened_error(): @@ -4250,10 +4316,12 @@ async def test_update_tensorboard_run_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_run == gca_tensorboard_run.TensorboardRun( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].tensorboard_run + mock_val = gca_tensorboard_run.TensorboardRun(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 @@ -4442,7 +4510,9 @@ def test_list_tensorboard_runs_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_tensorboard_runs_flattened_error(): @@ -4482,7 +4552,9 @@ async def test_list_tensorboard_runs_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4838,7 +4910,9 @@ def test_delete_tensorboard_run_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_tensorboard_run_flattened_error(): @@ -4878,7 +4952,9 @@ async def test_delete_tensorboard_run_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5077,12 +5153,16 @@ def test_batch_create_tensorboard_time_series_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].requests == [ + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [ tensorboard_service.CreateTensorboardTimeSeriesRequest( parent="parent_value" ) ] + assert arg == mock_val def test_batch_create_tensorboard_time_series_flattened_error(): @@ -5137,12 +5217,16 @@ async def test_batch_create_tensorboard_time_series_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].requests == [ + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].requests + mock_val = [ tensorboard_service.CreateTensorboardTimeSeriesRequest( parent="parent_value" ) ] + assert arg == mock_val @pytest.mark.asyncio @@ -5371,12 +5455,12 @@ def test_create_tensorboard_time_series_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].tensorboard_time_series == gca_tensorboard_time_series.TensorboardTimeSeries( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard_time_series + mock_val = gca_tensorboard_time_series.TensorboardTimeSeries(name="name_value") + assert arg == mock_val def test_create_tensorboard_time_series_flattened_error(): @@ -5425,12 +5509,12 @@ async def test_create_tensorboard_time_series_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[ - 0 - ].tensorboard_time_series == gca_tensorboard_time_series.TensorboardTimeSeries( - name="name_value" - ) + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tensorboard_time_series + mock_val = gca_tensorboard_time_series.TensorboardTimeSeries(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -5652,7 +5736,9 @@ def test_get_tensorboard_time_series_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_tensorboard_time_series_flattened_error(): @@ -5692,7 +5778,9 @@ async def test_get_tensorboard_time_series_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5921,12 +6009,12 @@ def test_update_tensorboard_time_series_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[ - 0 - ].tensorboard_time_series == gca_tensorboard_time_series.TensorboardTimeSeries( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].tensorboard_time_series + mock_val = gca_tensorboard_time_series.TensorboardTimeSeries(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_tensorboard_time_series_flattened_error(): @@ -5975,12 +6063,12 @@ async def test_update_tensorboard_time_series_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[ - 0 - ].tensorboard_time_series == gca_tensorboard_time_series.TensorboardTimeSeries( - name="name_value" - ) - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].tensorboard_time_series + mock_val = gca_tensorboard_time_series.TensorboardTimeSeries(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 @@ -6172,7 +6260,9 @@ def test_list_tensorboard_time_series_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_tensorboard_time_series_flattened_error(): @@ -6213,7 +6303,9 @@ async def test_list_tensorboard_time_series_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6586,7 +6678,9 @@ def test_delete_tensorboard_time_series_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_tensorboard_time_series_flattened_error(): @@ -6626,7 +6720,9 @@ async def test_delete_tensorboard_time_series_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -6824,7 +6920,9 @@ def test_batch_read_tensorboard_time_series_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].tensorboard == "tensorboard_value" + arg = args[0].tensorboard + mock_val = "tensorboard_value" + assert arg == mock_val def test_batch_read_tensorboard_time_series_data_flattened_error(): @@ -6869,7 +6967,9 @@ async def test_batch_read_tensorboard_time_series_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].tensorboard == "tensorboard_value" + arg = args[0].tensorboard + mock_val = "tensorboard_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7064,7 +7164,9 @@ def test_read_tensorboard_time_series_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_time_series == "tensorboard_time_series_value" + arg = args[0].tensorboard_time_series + mock_val = "tensorboard_time_series_value" + assert arg == mock_val def test_read_tensorboard_time_series_data_flattened_error(): @@ -7107,7 +7209,9 @@ async def test_read_tensorboard_time_series_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_time_series == "tensorboard_time_series_value" + arg = args[0].tensorboard_time_series + mock_val = "tensorboard_time_series_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7300,7 +7404,9 @@ def test_read_tensorboard_blob_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].time_series == "time_series_value" + arg = args[0].time_series + mock_val = "time_series_value" + assert arg == mock_val def test_read_tensorboard_blob_data_flattened_error(): @@ -7343,7 +7449,9 @@ async def test_read_tensorboard_blob_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].time_series == "time_series_value" + arg = args[0].time_series + mock_val = "time_series_value" + assert arg == mock_val @pytest.mark.asyncio @@ -7543,12 +7651,16 @@ def test_write_tensorboard_experiment_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_experiment == "tensorboard_experiment_value" - assert args[0].write_run_data_requests == [ + arg = args[0].tensorboard_experiment + mock_val = "tensorboard_experiment_value" + assert arg == mock_val + arg = args[0].write_run_data_requests + mock_val = [ tensorboard_service.WriteTensorboardRunDataRequest( tensorboard_run="tensorboard_run_value" ) ] + assert arg == mock_val def test_write_tensorboard_experiment_data_flattened_error(): @@ -7601,12 +7713,16 @@ async def test_write_tensorboard_experiment_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_experiment == "tensorboard_experiment_value" - assert args[0].write_run_data_requests == [ + arg = args[0].tensorboard_experiment + mock_val = "tensorboard_experiment_value" + assert arg == mock_val + arg = args[0].write_run_data_requests + mock_val = [ tensorboard_service.WriteTensorboardRunDataRequest( tensorboard_run="tensorboard_run_value" ) ] + assert arg == mock_val @pytest.mark.asyncio @@ -7805,12 +7921,16 @@ def test_write_tensorboard_run_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_run == "tensorboard_run_value" - assert args[0].time_series_data == [ + arg = args[0].tensorboard_run + mock_val = "tensorboard_run_value" + assert arg == mock_val + arg = args[0].time_series_data + mock_val = [ tensorboard_data.TimeSeriesData( tensorboard_time_series_id="tensorboard_time_series_id_value" ) ] + assert arg == mock_val def test_write_tensorboard_run_data_flattened_error(): @@ -7863,12 +7983,16 @@ async def test_write_tensorboard_run_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_run == "tensorboard_run_value" - assert args[0].time_series_data == [ + arg = args[0].tensorboard_run + mock_val = "tensorboard_run_value" + assert arg == mock_val + arg = args[0].time_series_data + mock_val = [ tensorboard_data.TimeSeriesData( tensorboard_time_series_id="tensorboard_time_series_id_value" ) ] + assert arg == mock_val @pytest.mark.asyncio @@ -8074,7 +8198,9 @@ def test_export_tensorboard_time_series_data_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_time_series == "tensorboard_time_series_value" + arg = args[0].tensorboard_time_series + mock_val = "tensorboard_time_series_value" + assert arg == mock_val def test_export_tensorboard_time_series_data_flattened_error(): @@ -8119,7 +8245,9 @@ async def test_export_tensorboard_time_series_data_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].tensorboard_time_series == "tensorboard_time_series_value" + arg = args[0].tensorboard_time_series + mock_val = "tensorboard_time_series_value" + assert arg == mock_val @pytest.mark.asyncio diff --git a/tests/unit/gapic/aiplatform_v1beta1/test_vizier_service.py b/tests/unit/gapic/aiplatform_v1beta1/test_vizier_service.py index 713b669e96..06287c35d1 100644 --- a/tests/unit/gapic/aiplatform_v1beta1/test_vizier_service.py +++ b/tests/unit/gapic/aiplatform_v1beta1/test_vizier_service.py @@ -653,8 +653,12 @@ def test_create_study_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].study == gca_study.Study(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].study + mock_val = gca_study.Study(name="name_value") + assert arg == mock_val def test_create_study_flattened_error(): @@ -692,8 +696,12 @@ async def test_create_study_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].study == gca_study.Study(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].study + mock_val = gca_study.Study(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -875,7 +883,9 @@ def test_get_study_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_study_flattened_error(): @@ -909,7 +919,9 @@ async def test_get_study_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1077,7 +1089,9 @@ def test_list_studies_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_studies_flattened_error(): @@ -1113,7 +1127,9 @@ async def test_list_studies_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1395,7 +1411,9 @@ def test_delete_study_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_study_flattened_error(): @@ -1429,7 +1447,9 @@ async def test_delete_study_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1609,7 +1629,9 @@ def test_lookup_study_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_lookup_study_flattened_error(): @@ -1643,7 +1665,9 @@ async def test_lookup_study_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1965,8 +1989,12 @@ def test_create_trial_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].trial == study.Trial(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].trial + mock_val = study.Trial(name="name_value") + assert arg == mock_val def test_create_trial_flattened_error(): @@ -2004,8 +2032,12 @@ async def test_create_trial_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].trial == study.Trial(name="name_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].trial + mock_val = study.Trial(name="name_value") + assert arg == mock_val @pytest.mark.asyncio @@ -2195,7 +2227,9 @@ def test_get_trial_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_trial_flattened_error(): @@ -2229,7 +2263,9 @@ async def test_get_trial_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2397,7 +2433,9 @@ def test_list_trials_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_trials_flattened_error(): @@ -2433,7 +2471,9 @@ async def test_list_trials_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3030,7 +3070,9 @@ def test_delete_trial_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_trial_flattened_error(): @@ -3064,7 +3106,9 @@ async def test_delete_trial_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3541,7 +3585,9 @@ def test_list_optimal_trials_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_optimal_trials_flattened_error(): @@ -3579,7 +3625,9 @@ async def test_list_optimal_trials_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio