Skip to content

Commit 96ce738

Browse files
authored
feat: Add support to create TensorboardExperiment (#909)
1 parent 9d51b1e commit 96ce738

File tree

5 files changed

+428
-14
lines changed

5 files changed

+428
-14
lines changed

google/cloud/aiplatform/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
HyperparameterTuningJob,
4848
)
4949
from google.cloud.aiplatform.pipeline_jobs import PipelineJob
50-
from google.cloud.aiplatform.tensorboard import Tensorboard
50+
from google.cloud.aiplatform.tensorboard import Tensorboard, TensorboardExperiment
5151
from google.cloud.aiplatform.training_jobs import (
5252
CustomTrainingJob,
5353
CustomContainerTrainingJob,
@@ -105,8 +105,9 @@
105105
"Model",
106106
"PipelineJob",
107107
"TabularDataset",
108+
"Tensorboard",
109+
"TensorboardExperiment",
108110
"TextDataset",
109111
"TimeSeriesDataset",
110112
"VideoDataset",
111-
"Tensorboard",
112113
)

google/cloud/aiplatform/tensorboard/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
# limitations under the License.
1616
#
1717

18-
from google.cloud.aiplatform.tensorboard.tensorboard_resource import Tensorboard
18+
from google.cloud.aiplatform.tensorboard.tensorboard_resource import (
19+
Tensorboard,
20+
TensorboardExperiment,
21+
)
1922

2023

21-
__all__ = ("Tensorboard",)
24+
__all__ = ("Tensorboard", "TensorboardExperiment")

google/cloud/aiplatform/tensorboard/tensorboard_resource.py

Lines changed: 243 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@
1515
# limitations under the License.
1616
#
1717

18-
from typing import Optional, Sequence, Dict, Tuple
18+
from typing import Dict, List, Optional, Sequence, Tuple
1919

2020
from google.auth import credentials as auth_credentials
2121
from google.protobuf import field_mask_pb2
2222

2323
from google.cloud.aiplatform import base
2424
from google.cloud.aiplatform.compat.types import tensorboard as gca_tensorboard
25+
from google.cloud.aiplatform.compat.types import (
26+
tensorboard_experiment as gca_tensorboard_experiment,
27+
)
2528
from google.cloud.aiplatform import initializer
2629
from google.cloud.aiplatform import utils
2730

@@ -176,12 +179,7 @@ def create(
176179

177180
_LOGGER.log_create_complete(cls, created_tensorboard, "tb")
178181

179-
return cls(
180-
tensorboard_name=created_tensorboard.name,
181-
project=project or initializer.global_config.project,
182-
location=location or initializer.global_config.location,
183-
credentials=credentials,
184-
)
182+
return cls(tensorboard_name=created_tensorboard.name, credentials=credentials,)
185183

186184
def update(
187185
self,
@@ -233,8 +231,7 @@ def update(
233231
Overrides encryption_spec_key_name set in aiplatform.init.
234232
235233
Returns:
236-
tensorboard (Tensorboard):
237-
The managed tensorboard resource.
234+
Tensorboard: The managed tensorboard resource.
238235
"""
239236
update_mask = list()
240237

@@ -285,3 +282,240 @@ def update(
285282
_LOGGER.log_action_completed_against_resource("tensorboard", "updated", self)
286283

287284
return self
285+
286+
287+
class TensorboardExperiment(_TensorboardServiceResource):
288+
"""Managed tensorboard resource for Vertex AI."""
289+
290+
_resource_noun = "experiments"
291+
_getter_method = "get_tensorboard_experiment"
292+
_list_method = "list_tensorboard_experiments"
293+
_delete_method = "delete_tensorboard_experiment"
294+
_parse_resource_name_method = "parse_tensorboard_experiment_path"
295+
_format_resource_name_method = "tensorboard_experiment_path"
296+
297+
def __init__(
298+
self,
299+
tensorboard_experiment_name: str,
300+
tensorboard_id: Optional[str] = None,
301+
project: Optional[str] = None,
302+
location: Optional[str] = None,
303+
credentials: Optional[auth_credentials.Credentials] = None,
304+
):
305+
"""Retrieves an existing tensorboard experiment given a tensorboard experiment name or ID.
306+
307+
Example Usage:
308+
309+
tb_exp = aiplatform.TensorboardExperiment(
310+
tensorboard_experiment_name= "projects/123/locations/us-central1/tensorboards/456/experiments/678"
311+
)
312+
313+
tb_exp = aiplatform.TensorboardExperiment(
314+
tensorboard_experiment_name= "678"
315+
tensorboard_id = "456"
316+
)
317+
318+
Args:
319+
tensorboard_experiment_name (str):
320+
Required. A fully-qualified tensorboard experiment resource name or resource ID.
321+
Example: "projects/123/locations/us-central1/tensorboards/456/experiments/678" or
322+
"678" when tensorboard_id is passed and project and location are initialized or passed.
323+
tensorboard_id (str):
324+
Optional. A tensorboard resource ID.
325+
project (str):
326+
Optional. Project to retrieve tensorboard from. If not set, project
327+
set in aiplatform.init will be used.
328+
location (str):
329+
Optional. Location to retrieve tensorboard from. If not set, location
330+
set in aiplatform.init will be used.
331+
credentials (auth_credentials.Credentials):
332+
Optional. Custom credentials to use to retrieve this Tensorboard. Overrides
333+
credentials set in aiplatform.init.
334+
"""
335+
336+
super().__init__(
337+
project=project,
338+
location=location,
339+
credentials=credentials,
340+
resource_name=tensorboard_experiment_name,
341+
)
342+
self._gca_resource = self._get_gca_resource(
343+
resource_name=tensorboard_experiment_name,
344+
parent_resource_name_fields={Tensorboard._resource_noun: tensorboard_id}
345+
if tensorboard_id
346+
else tensorboard_id,
347+
)
348+
349+
@classmethod
350+
def create(
351+
cls,
352+
tensorboard_experiment_id: str,
353+
tensorboard_name: str,
354+
display_name: Optional[str] = None,
355+
description: Optional[str] = None,
356+
labels: Optional[Dict[str, str]] = None,
357+
project: Optional[str] = None,
358+
location: Optional[str] = None,
359+
credentials: Optional[auth_credentials.Credentials] = None,
360+
request_metadata: Sequence[Tuple[str, str]] = (),
361+
) -> "TensorboardExperiment":
362+
"""Creates a new TensorboardExperiment.
363+
364+
Example Usage:
365+
366+
tb = aiplatform.TensorboardExperiment.create(
367+
tensorboard_experiment_id='my-experiment'
368+
tensorboard_id='456'
369+
display_name='my display name',
370+
description='my description',
371+
labels={
372+
'key1': 'value1',
373+
'key2': 'value2'
374+
}
375+
)
376+
377+
Args:
378+
tensorboard_experiment_id (str):
379+
Required. The ID to use for the Tensorboard experiment,
380+
which will become the final component of the Tensorboard
381+
experiment's resource name.
382+
383+
This value should be 1-128 characters, and valid
384+
characters are /[a-z][0-9]-/.
385+
386+
This corresponds to the ``tensorboard_experiment_id`` field
387+
on the ``request`` instance; if ``request`` is provided, this
388+
should not be set.
389+
tensorboard_name (str):
390+
Required. The resource name or ID of the Tensorboard to create
391+
the TensorboardExperiment in. Format of resource name:
392+
``projects/{project}/locations/{location}/tensorboards/{tensorboard}``
393+
display_name (str):
394+
Optional. The user-defined name of the Tensorboard Experiment.
395+
The name can be up to 128 characters long and can be consist
396+
of any UTF-8 characters.
397+
description (str):
398+
Optional. Description of this Tensorboard Experiment.
399+
labels (Dict[str, str]):
400+
Optional. Labels with user-defined metadata to organize your Tensorboards.
401+
Label keys and values can be no longer than 64 characters
402+
(Unicode codepoints), can only contain lowercase letters, numeric
403+
characters, underscores and dashes. International characters are allowed.
404+
No more than 64 user labels can be associated with one Tensorboard
405+
(System labels are excluded).
406+
See https://goo.gl/xmQnxf for more information and examples of labels.
407+
System reserved label keys are prefixed with "aiplatform.googleapis.com/"
408+
and are immutable.
409+
project (str):
410+
Optional. Project to upload this model to. Overrides project set in
411+
aiplatform.init.
412+
location (str):
413+
Optional. Location to upload this model to. Overrides location set in
414+
aiplatform.init.
415+
credentials (auth_credentials.Credentials):
416+
Optional. Custom credentials to use to upload this model. Overrides
417+
credentials set in aiplatform.init.
418+
request_metadata (Sequence[Tuple[str, str]]):
419+
Optional. Strings which should be sent along with the request as metadata.
420+
Returns:
421+
TensorboardExperiment: The TensorboardExperiment resource.
422+
"""
423+
424+
if display_name:
425+
utils.validate_display_name(display_name)
426+
427+
if labels:
428+
utils.validate_labels(labels)
429+
430+
api_client = cls._instantiate_client(location=location, credentials=credentials)
431+
432+
parent = utils.full_resource_name(
433+
resource_name=tensorboard_name,
434+
resource_noun=Tensorboard._resource_noun,
435+
parse_resource_name_method=Tensorboard._parse_resource_name,
436+
format_resource_name_method=Tensorboard._format_resource_name,
437+
project=project,
438+
location=location,
439+
)
440+
441+
gapic_tensorboard_experiment = gca_tensorboard_experiment.TensorboardExperiment(
442+
display_name=display_name, description=description, labels=labels,
443+
)
444+
445+
_LOGGER.log_create_with_lro(cls)
446+
447+
tensorboard_experiment = api_client.create_tensorboard_experiment(
448+
parent=parent,
449+
tensorboard_experiment=gapic_tensorboard_experiment,
450+
tensorboard_experiment_id=tensorboard_experiment_id,
451+
metadata=request_metadata,
452+
)
453+
454+
_LOGGER.log_create_complete(cls, tensorboard_experiment, "tb experiment")
455+
456+
return cls(
457+
tensorboard_experiment_name=tensorboard_experiment.name,
458+
credentials=credentials,
459+
)
460+
461+
@classmethod
462+
def list(
463+
cls,
464+
tensorboard_name: str,
465+
filter: Optional[str] = None,
466+
order_by: Optional[str] = None,
467+
project: Optional[str] = None,
468+
location: Optional[str] = None,
469+
credentials: Optional[auth_credentials.Credentials] = None,
470+
) -> List["TensorboardExperiment"]:
471+
"""List TensorboardExperiemnts in a Tensorboard resource.
472+
473+
Example Usage:
474+
475+
aiplatform.TensorboardExperiment.list(
476+
tensorboard_name='projects/my-project/locations/us-central1/tensorboards/123'
477+
)
478+
479+
Args:
480+
tensorboard_name(str):
481+
Required. The resource name or resource ID of the
482+
Tensorboard to list
483+
TensorboardExperiments. Format, if resource name:
484+
'projects/{project}/locations/{location}/tensorboards/{tensorboard}'
485+
filter (str):
486+
Optional. An expression for filtering the results of the request.
487+
For field names both snake_case and camelCase are supported.
488+
order_by (str):
489+
Optional. A comma-separated list of fields to order by, sorted in
490+
ascending order. Use "desc" after a field name for descending.
491+
Supported fields: `display_name`, `create_time`, `update_time`
492+
project (str):
493+
Optional. Project to retrieve list from. If not set, project
494+
set in aiplatform.init will be used.
495+
location (str):
496+
Optional. Location to retrieve list from. If not set, location
497+
set in aiplatform.init will be used.
498+
credentials (auth_credentials.Credentials):
499+
Optional. Custom credentials to use to retrieve list. Overrides
500+
credentials set in aiplatform.init.
501+
Returns:
502+
List[TensorboardExperiment] - A list of TensorboardExperiments
503+
"""
504+
505+
parent = utils.full_resource_name(
506+
resource_name=tensorboard_name,
507+
resource_noun=Tensorboard._resource_noun,
508+
parse_resource_name_method=Tensorboard._parse_resource_name,
509+
format_resource_name_method=Tensorboard._format_resource_name,
510+
project=project,
511+
location=location,
512+
)
513+
514+
return super()._list(
515+
filter=filter,
516+
order_by=order_by,
517+
project=project,
518+
location=location,
519+
credentials=credentials,
520+
parent=parent,
521+
)

tests/system/aiplatform/test_tensorboard.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,25 @@ def test_create_and_get_tensorboard(self, shared_state):
4242
list_tb = aiplatform.Tensorboard.list()
4343

4444
assert len(list_tb) > 0
45+
46+
tb_experiment = aiplatform.TensorboardExperiment.create(
47+
tensorboard_experiment_id="vertex-sdk-e2e-test-experiment",
48+
tensorboard_name=tb.resource_name,
49+
display_name=self._make_display_name("tensorboard_experiment"),
50+
description="Vertex SDK Integration test.",
51+
labels={"test": "labels"},
52+
)
53+
54+
shared_state["resources"].append(tb_experiment)
55+
56+
get_tb_experiment = aiplatform.TensorboardExperiment(
57+
tb_experiment.resource_name
58+
)
59+
60+
assert tb_experiment.resource_name == get_tb_experiment.resource_name
61+
62+
list_tb_experiment = aiplatform.TensorboardExperiment.list(
63+
tensorboard_name=tb.resource_name
64+
)
65+
66+
assert len(list_tb_experiment) > 0

0 commit comments

Comments
 (0)