Skip to content

Commit

Permalink
feat(sdk): add client methods to cli
Browse files Browse the repository at this point in the history
  • Loading branch information
connor-mccarthy committed Apr 25, 2022
1 parent fbfeadd commit ae767fe
Show file tree
Hide file tree
Showing 4 changed files with 264 additions and 128 deletions.
100 changes: 66 additions & 34 deletions sdk/python/kfp/cli/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

import click
import kfp_server_api
from kfp.cli.output import OutputFormat, print_output
from kfp.cli.output import OutputFormat
from kfp.cli.output import print_output
from kfp_server_api.models.api_experiment import ApiExperiment


Expand All @@ -14,33 +15,34 @@ def experiment():


@experiment.command()
@click.option('-d', '--description', help="Description of the experiment.")
@click.argument("name")
@click.option('-d', '--description', help='Description of the experiment.')
@click.argument('name')
@click.pass_context
def create(ctx: click.Context, description: str, name: str):
"""Create an experiment."""
client = ctx.obj["client"]
output_format = ctx.obj["output"]
client = ctx.obj['client']
output_format = ctx.obj['output']

response = client.create_experiment(name, description=description)
_display_experiment(response, output_format)
click.echo('Experiment created.')


@experiment.command()
@click.option(
'--page-token', default='', help="Token for starting of the page.")
'--page-token', default='', help='Token for starting of the page.')
@click.option(
'-m', '--max-size', default=100, help="Max size of the listed experiments.")
'-m', '--max-size', default=100, help='Max size of the listed experiments.')
@click.option(
'--sort-by',
default="created_at desc",
default='created_at desc',
help="Can be '[field_name]', '[field_name] desc'. For example, 'name desc'."
)
@click.option(
'--filter',
help=(
"filter: A url-encoded, JSON-serialized Filter protocol buffer "
"(see [filter.proto](https://github.com/kubeflow/pipelines/blob/master/backend/api/filter.proto))."
'filter: A url-encoded, JSON-serialized Filter protocol buffer '
'(see [filter.proto](https://github.com/kubeflow/pipelines/blob/master/backend/api/filter.proto)).'
))
@click.pass_context
def list(ctx: click.Context, page_token: str, max_size: int, sort_by: str,
Expand All @@ -60,85 +62,115 @@ def list(ctx: click.Context, page_token: str, max_size: int, sort_by: str,
if output_format == OutputFormat.json.name:
msg = json.dumps([])
else:
msg = "No experiments found"
msg = 'No experiments found'
click.echo(msg)


@experiment.command()
@click.argument("experiment-id")
@click.argument('experiment-id')
@click.pass_context
def get(ctx: click.Context, experiment_id: str):
"""Get detailed information about an experiment."""
client = ctx.obj["client"]
output_format = ctx.obj["output"]
client = ctx.obj['client']
output_format = ctx.obj['output']

response = client.get_experiment(experiment_id)
_display_experiment(response, output_format)


@experiment.command()
@click.argument("experiment-id")
@click.argument('experiment-id')
@click.pass_context
def delete(ctx: click.Context, experiment_id: str):
"""Delete an experiment."""

confirmation = "Caution. The RunDetails page could have an issue" \
" when it renders a run that has no experiment." \
" Do you want to continue?"
confirmation = 'Caution. The RunDetails page could have an issue' \
' when it renders a run that has no experiment.' \
' Do you want to continue?'
if not click.confirm(confirmation):
return

client = ctx.obj["client"]
client = ctx.obj['client']

client.delete_experiment(experiment_id)
click.echo(f"{experiment_id} is deleted.")
click.echo(f'Experiment {experiment_id} deleted.')


def _display_experiments(experiments: List[ApiExperiment],
output_format: OutputFormat):
headers = ["Experiment ID", "Name", "Created at"]
headers = ['Experiment ID', 'Name', 'Created at']
data = [
[exp.id, exp.name, exp.created_at.isoformat()] for exp in experiments
]
print_output(data, headers, output_format, table_format="grid")
print_output(data, headers, output_format, table_format='grid')


def _display_experiment(exp: kfp_server_api.ApiExperiment,
output_format: OutputFormat):
table = [
["ID", exp.id],
["Name", exp.name],
["Description", exp.description],
["Created at", exp.created_at.isoformat()],
['ID', exp.id],
['Name', exp.name],
['Description', exp.description],
['Created at', exp.created_at.isoformat()],
]
if output_format == OutputFormat.table.name:
print_output([], ["Experiment Details"], output_format)
print_output(table, [], output_format, table_format="plain")
print_output([], ['Experiment Details'], output_format)
print_output(table, [], output_format, table_format='plain')
elif output_format == OutputFormat.json.name:
print_output(dict(table), [], output_format)


@experiment.command()
@click.option(
"--experiment-id",
'--experiment-id',
default=None,
help="The ID of the experiment to archive, can only supply either an experiment ID or name."
help='The ID of the experiment to archive, can only supply either an experiment ID or name.'
)
@click.option(
"--experiment-name",
'--experiment-name',
default=None,
help="The name of the experiment to archive, can only supply either an experiment ID or name."
help='The name of the experiment to archive, can only supply either an experiment ID or name.'
)
@click.pass_context
def archive(ctx: click.Context, experiment_id: str, experiment_name: str):
"""Archive an experiment."""
client = ctx.obj["client"]
client = ctx.obj['client']

if (experiment_id is None) == (experiment_name is None):
raise ValueError(
'Either --experiment-id or --experiment-name is required.')

if not experiment_id:
experiment = client.get_experiment(experiment_name=experiment_name)
experiment_id = experiment.id

client.archive_experiment(experiment_id=experiment_id)
click.echo(f'Experiment {experiment_id} archived.')


@experiment.command()
@click.option(
'--experiment-id',
default=None,
help='The ID of the experiment to archive, can only supply either an experiment ID or name.'
)
@click.option(
'--experiment-name',
default=None,
help='The name of the experiment to archive, can only supply either an experiment ID or name.'
)
@click.pass_context
def unarchive(ctx: click.Context, experiment_id: str, experiment_name: str):
"""Unarchive an experiment."""
client = ctx.obj['client']

if (experiment_id is None) == (experiment_name is None):
raise ValueError('Either experiment_id or experiment_name is required')
raise ValueError(
'Either --expriment-id or --experiment-name is required.')

if not experiment_id:
experiment = client.get_experiment(experiment_name=experiment_name)
experiment_id = experiment.id

client.archive_experiment(experiment_id=experiment_id)
click.echo(f'Experiment {experiment_id} unarchived.')
Loading

0 comments on commit ae767fe

Please sign in to comment.