Skip to content

Commit c40ec85

Browse files
authored
feat: Upgrade Tensorboard from v1beta1 to v1 (#849)
1 parent 8b9376e commit c40ec85

File tree

10 files changed

+117
-100
lines changed

10 files changed

+117
-100
lines changed

google/cloud/aiplatform/compat/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,14 @@
7777
types.specialist_pool = types.specialist_pool_v1beta1
7878
types.specialist_pool_service = types.specialist_pool_service_v1beta1
7979
types.study = types.study_v1beta1
80-
types.training_pipeline = types.training_pipeline_v1beta1
80+
types.tensorboard = types.tensorboard_v1beta1
8181
types.tensorboard_service = types.tensorboard_service_v1beta1
8282
types.tensorboard_data = types.tensorboard_data_v1beta1
8383
types.tensorboard_experiment = types.tensorboard_experiment_v1beta1
8484
types.tensorboard_run = types.tensorboard_run_v1beta1
8585
types.tensorboard_service = types.tensorboard_service_v1beta1
8686
types.tensorboard_time_series = types.tensorboard_time_series_v1beta1
87+
types.training_pipeline = types.training_pipeline_v1beta1
8788

8889
if DEFAULT_VERSION == V1:
8990

@@ -135,6 +136,13 @@
135136
types.specialist_pool = types.specialist_pool_v1
136137
types.specialist_pool_service = types.specialist_pool_service_v1
137138
types.study = types.study_v1
139+
types.tensorboard = types.tensorboard_v1
140+
types.tensorboard_service = types.tensorboard_service_v1
141+
types.tensorboard_data = types.tensorboard_data_v1
142+
types.tensorboard_experiment = types.tensorboard_experiment_v1
143+
types.tensorboard_run = types.tensorboard_run_v1
144+
types.tensorboard_service = types.tensorboard_service_v1
145+
types.tensorboard_time_series = types.tensorboard_time_series_v1
138146
types.training_pipeline = types.training_pipeline_v1
139147

140148
__all__ = (

google/cloud/aiplatform/compat/services/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767
from google.cloud.aiplatform_v1.services.specialist_pool_service import (
6868
client as specialist_pool_service_client_v1,
6969
)
70+
from google.cloud.aiplatform_v1.services.tensorboard_service import (
71+
client as tensorboard_service_client_v1,
72+
)
7073

7174
__all__ = (
7275
# v1
@@ -78,6 +81,7 @@
7881
pipeline_service_client_v1,
7982
prediction_service_client_v1,
8083
specialist_pool_service_client_v1,
84+
tensorboard_service_client_v1,
8185
# v1beta1
8286
dataset_service_client_v1beta1,
8387
endpoint_service_client_v1beta1,

google/cloud/aiplatform/compat/types/__init__.py

+14-4
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@
5757
specialist_pool as specialist_pool_v1beta1,
5858
specialist_pool_service as specialist_pool_service_v1beta1,
5959
study as study_v1beta1,
60-
training_pipeline as training_pipeline_v1beta1,
6160
tensorboard as tensorboard_v1beta1,
6261
tensorboard_data as tensorboard_data_v1beta1,
6362
tensorboard_experiment as tensorboard_experiment_v1beta1,
6463
tensorboard_run as tensorboard_run_v1beta1,
6564
tensorboard_service as tensorboard_service_v1beta1,
6665
tensorboard_time_series as tensorboard_time_series_v1beta1,
66+
training_pipeline as training_pipeline_v1beta1,
6767
)
6868
from google.cloud.aiplatform_v1.types import (
6969
accelerator_type as accelerator_type_v1,
@@ -107,6 +107,12 @@
107107
specialist_pool as specialist_pool_v1,
108108
specialist_pool_service as specialist_pool_service_v1,
109109
study as study_v1,
110+
tensorboard as tensorboard_v1,
111+
tensorboard_data as tensorboard_data_v1,
112+
tensorboard_experiment as tensorboard_experiment_v1,
113+
tensorboard_run as tensorboard_run_v1,
114+
tensorboard_service as tensorboard_service_v1,
115+
tensorboard_time_series as tensorboard_time_series_v1,
110116
training_pipeline as training_pipeline_v1,
111117
)
112118

@@ -152,6 +158,12 @@
152158
prediction_service_v1,
153159
specialist_pool_v1,
154160
specialist_pool_service_v1,
161+
tensorboard_v1,
162+
tensorboard_data_v1,
163+
tensorboard_experiment_v1,
164+
tensorboard_run_v1,
165+
tensorboard_service_v1,
166+
tensorboard_time_series_v1,
155167
training_pipeline_v1,
156168
# v1beta1
157169
accelerator_type_v1beta1,
@@ -194,13 +206,11 @@
194206
prediction_service_v1beta1,
195207
specialist_pool_v1beta1,
196208
specialist_pool_service_v1beta1,
197-
training_pipeline_v1beta1,
198-
metadata_service_v1beta1,
199209
tensorboard_v1beta1,
200-
tensorboard_service_v1beta1,
201210
tensorboard_data_v1beta1,
202211
tensorboard_experiment_v1beta1,
203212
tensorboard_run_v1beta1,
204213
tensorboard_service_v1beta1,
205214
tensorboard_time_series_v1beta1,
215+
training_pipeline_v1beta1,
206216
)

google/cloud/aiplatform/jobs.py

+2-20
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,10 @@
3535
batch_prediction_job as gca_bp_job_compat,
3636
completion_stats as gca_completion_stats,
3737
custom_job as gca_custom_job_compat,
38-
custom_job_v1beta1 as gca_custom_job_v1beta1,
3938
explanation as gca_explanation_compat,
4039
io as gca_io_compat,
4140
job_state as gca_job_state,
4241
hyperparameter_tuning_job as gca_hyperparameter_tuning_job_compat,
43-
hyperparameter_tuning_job_v1beta1 as gca_hyperparameter_tuning_job_v1beta1,
4442
machine_resources as gca_machine_resources_compat,
4543
study as gca_study_compat,
4644
)
@@ -1388,17 +1386,11 @@ def run(
13881386
self._gca_resource.job_spec.enable_web_access = enable_web_access
13891387

13901388
if tensorboard:
1391-
v1beta1_gca_resource = gca_custom_job_v1beta1.CustomJob()
1392-
v1beta1_gca_resource._pb.MergeFromString(
1393-
self._gca_resource._pb.SerializeToString()
1394-
)
1395-
self._gca_resource = v1beta1_gca_resource
13961389
self._gca_resource.job_spec.tensorboard = tensorboard
13971390

13981391
_LOGGER.log_create_with_lro(self.__class__)
13991392

1400-
version = "v1beta1" if tensorboard else "v1"
1401-
self._gca_resource = self.api_client.select_version(version).create_custom_job(
1393+
self._gca_resource = self.api_client.create_custom_job(
14021394
parent=self._parent, custom_job=self._gca_resource
14031395
)
14041396

@@ -1773,21 +1765,11 @@ def run(
17731765
self._gca_resource.trial_job_spec.enable_web_access = enable_web_access
17741766

17751767
if tensorboard:
1776-
v1beta1_gca_resource = (
1777-
gca_hyperparameter_tuning_job_v1beta1.HyperparameterTuningJob()
1778-
)
1779-
v1beta1_gca_resource._pb.MergeFromString(
1780-
self._gca_resource._pb.SerializeToString()
1781-
)
1782-
self._gca_resource = v1beta1_gca_resource
17831768
self._gca_resource.trial_job_spec.tensorboard = tensorboard
17841769

17851770
_LOGGER.log_create_with_lro(self.__class__)
17861771

1787-
version = "v1beta1" if tensorboard else "v1"
1788-
self._gca_resource = self.api_client.select_version(
1789-
version
1790-
).create_hyperparameter_tuning_job(
1772+
self._gca_resource = self.api_client.create_hyperparameter_tuning_job(
17911773
parent=self._parent, hyperparameter_tuning_job=self._gca_resource
17921774
)
17931775

google/cloud/aiplatform/tensorboard/tensorboard.py

+3-9
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,13 @@
1818
from typing import Optional, Sequence, Dict, Tuple
1919

2020
from google.auth import credentials as auth_credentials
21+
from google.protobuf import field_mask_pb2
2122

2223
from google.cloud.aiplatform import base
23-
from google.cloud.aiplatform import compat
24+
from google.cloud.aiplatform.compat.types import tensorboard as gca_tensorboard
2425
from google.cloud.aiplatform import initializer
2526
from google.cloud.aiplatform import utils
2627

27-
28-
from google.cloud.aiplatform.compat.types import tensorboard_v1beta1 as gca_tensorboard
29-
30-
from google.protobuf import field_mask_pb2
31-
3228
_LOGGER = base.Logger(__name__)
3329

3430

@@ -156,8 +152,7 @@ def create(
156152
)
157153

158154
encryption_spec = initializer.global_config.get_encryption_spec(
159-
encryption_spec_key_name=encryption_spec_key_name,
160-
select_version=compat.V1BETA1,
155+
encryption_spec_key_name=encryption_spec_key_name
161156
)
162157

163158
gapic_tensorboard = gca_tensorboard.Tensorboard(
@@ -254,7 +249,6 @@ def update(
254249
if encryption_spec_key_name:
255250
encryption_spec = initializer.global_config.get_encryption_spec(
256251
encryption_spec_key_name=encryption_spec_key_name,
257-
select_version=compat.V1BETA1,
258252
)
259253
update_mask.append("encryption_spec")
260254

google/cloud/aiplatform/utils/__init__.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
model_service_client_v1,
5252
pipeline_service_client_v1,
5353
prediction_service_client_v1,
54+
tensorboard_service_client_v1,
5455
)
5556

5657
from google.cloud.aiplatform.compat.types import (
@@ -67,6 +68,7 @@
6768
pipeline_service_client_v1beta1.PipelineServiceClient,
6869
job_service_client_v1beta1.JobServiceClient,
6970
metadata_service_client_v1beta1.MetadataServiceClient,
71+
tensorboard_service_client_v1beta1.TensorboardServiceClient,
7072
# v1
7173
dataset_service_client_v1.DatasetServiceClient,
7274
endpoint_service_client_v1.EndpointServiceClient,
@@ -75,6 +77,7 @@
7577
prediction_service_client_v1.PredictionServiceClient,
7678
pipeline_service_client_v1.PipelineServiceClient,
7779
job_service_client_v1.JobServiceClient,
80+
tensorboard_service_client_v1.TensorboardServiceClient,
7881
)
7982

8083
RESOURCE_NAME_PATTERN = re.compile(
@@ -506,8 +509,9 @@ class MetadataClientWithOverride(ClientWithOverride):
506509

507510
class TensorboardClientWithOverride(ClientWithOverride):
508511
_is_temporary = False
509-
_default_version = compat.V1BETA1
512+
_default_version = compat.DEFAULT_VERSION
510513
_version_map = (
514+
(compat.V1, tensorboard_service_client_v1.TensorboardServiceClient),
511515
(compat.V1BETA1, tensorboard_service_client_v1beta1.TensorboardServiceClient),
512516
)
513517

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Copyright 2021 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
from google.cloud import aiplatform
19+
from tests.system.aiplatform import e2e_base
20+
21+
22+
class TestTensorboard(e2e_base.TestEndToEnd):
23+
24+
_temp_prefix = "temp-vertex-sdk-e2e-test"
25+
26+
def test_create_and_get_tensorboard(self, shared_state):
27+
28+
aiplatform.init(
29+
project=e2e_base._PROJECT, location=e2e_base._LOCATION,
30+
)
31+
32+
display_name = self._make_display_name("tensorboard")
33+
34+
tb = aiplatform.Tensorboard.create(display_name=display_name)
35+
36+
shared_state["resources"] = [tb]
37+
38+
get_tb = aiplatform.Tensorboard(tb.resource_name)
39+
40+
assert tb.resource_name == get_tb.resource_name
41+
42+
list_tb = aiplatform.Tensorboard.list()
43+
44+
assert len(list_tb) > 0

tests/unit/aiplatform/test_custom_job.py

+17-34
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,12 @@
3131
from google.cloud import aiplatform
3232
from google.cloud.aiplatform import base
3333
from google.cloud.aiplatform.compat.types import custom_job as gca_custom_job_compat
34-
from google.cloud.aiplatform.compat.types import (
35-
custom_job_v1beta1 as gca_custom_job_v1beta1,
36-
)
3734
from google.cloud.aiplatform.compat.types import io as gca_io_compat
3835
from google.cloud.aiplatform.compat.types import job_state as gca_job_state_compat
3936
from google.cloud.aiplatform.compat.types import (
4037
encryption_spec as gca_encryption_spec_compat,
4138
)
4239
from google.cloud.aiplatform_v1.services.job_service import client as job_service_client
43-
from google.cloud.aiplatform_v1beta1.services.job_service import (
44-
client as job_service_client_v1beta1,
45-
)
4640

4741
_TEST_PROJECT = "test-project"
4842
_TEST_LOCATION = "us-central1"
@@ -114,29 +108,16 @@
114108
)
115109

116110

117-
def _get_custom_job_proto(state=None, name=None, error=None, version="v1"):
111+
def _get_custom_job_proto(state=None, name=None, error=None):
118112
custom_job_proto = copy.deepcopy(_TEST_BASE_CUSTOM_JOB_PROTO)
119113
custom_job_proto.name = name
120114
custom_job_proto.state = state
121115
custom_job_proto.error = error
122-
123-
if version == "v1beta1":
124-
v1beta1_custom_job_proto = gca_custom_job_v1beta1.CustomJob()
125-
v1beta1_custom_job_proto._pb.MergeFromString(
126-
custom_job_proto._pb.SerializeToString()
127-
)
128-
custom_job_proto = v1beta1_custom_job_proto
129-
custom_job_proto.job_spec.tensorboard = _TEST_TENSORBOARD_NAME
130-
131116
return custom_job_proto
132117

133118

134-
def _get_custom_job_proto_with_enable_web_access(
135-
state=None, name=None, error=None, version="v1"
136-
):
137-
custom_job_proto = _get_custom_job_proto(
138-
state=state, name=name, error=error, version=version
139-
)
119+
def _get_custom_job_proto_with_enable_web_access(state=None, name=None, error=None):
120+
custom_job_proto = _get_custom_job_proto(state=state, name=name, error=error)
140121
custom_job_proto.job_spec.enable_web_access = _TEST_ENABLE_WEB_ACCESS
141122
if state == gca_job_state_compat.JobState.JOB_STATE_RUNNING:
142123
custom_job_proto.web_access_uris = _TEST_WEB_ACCESS_URIS
@@ -260,24 +241,25 @@ def create_custom_job_mock_with_enable_web_access():
260241

261242

262243
@pytest.fixture
263-
def create_custom_job_mock_fail():
244+
def create_custom_job_mock_with_tensorboard():
264245
with mock.patch.object(
265246
job_service_client.JobServiceClient, "create_custom_job"
266247
) as create_custom_job_mock:
267-
create_custom_job_mock.side_effect = RuntimeError("Mock fail")
248+
custom_job_proto = _get_custom_job_proto(
249+
name=_TEST_CUSTOM_JOB_NAME,
250+
state=gca_job_state_compat.JobState.JOB_STATE_PENDING,
251+
)
252+
custom_job_proto.job_spec.tensorboard = _TEST_TENSORBOARD_NAME
253+
create_custom_job_mock.return_value = custom_job_proto
268254
yield create_custom_job_mock
269255

270256

271257
@pytest.fixture
272-
def create_custom_job_v1beta1_mock():
258+
def create_custom_job_mock_fail():
273259
with mock.patch.object(
274-
job_service_client_v1beta1.JobServiceClient, "create_custom_job"
260+
job_service_client.JobServiceClient, "create_custom_job"
275261
) as create_custom_job_mock:
276-
create_custom_job_mock.return_value = _get_custom_job_proto(
277-
name=_TEST_CUSTOM_JOB_NAME,
278-
state=gca_job_state_compat.JobState.JOB_STATE_PENDING,
279-
version="v1beta1",
280-
)
262+
create_custom_job_mock.side_effect = RuntimeError("Mock fail")
281263
yield create_custom_job_mock
282264

283265

@@ -573,7 +555,7 @@ def test_get_web_access_uris_job_succeeded(
573555

574556
@pytest.mark.parametrize("sync", [True, False])
575557
def test_create_custom_job_with_tensorboard(
576-
self, create_custom_job_v1beta1_mock, get_custom_job_mock, sync
558+
self, create_custom_job_mock_with_tensorboard, get_custom_job_mock, sync
577559
):
578560

579561
aiplatform.init(
@@ -601,9 +583,10 @@ def test_create_custom_job_with_tensorboard(
601583

602584
job.wait()
603585

604-
expected_custom_job = _get_custom_job_proto(version="v1beta1")
586+
expected_custom_job = _get_custom_job_proto()
587+
expected_custom_job.job_spec.tensorboard = _TEST_TENSORBOARD_NAME
605588

606-
create_custom_job_v1beta1_mock.assert_called_once_with(
589+
create_custom_job_mock_with_tensorboard.assert_called_once_with(
607590
parent=_TEST_PARENT, custom_job=expected_custom_job
608591
)
609592

0 commit comments

Comments
 (0)