Skip to content
This repository was archived by the owner on Aug 11, 2020. It is now read-only.

Commit fdee391

Browse files
committed
Merge remote-tracking branch 'origin/master' into run-restored
2 parents e616f7a + bdf07b6 commit fdee391

File tree

17 files changed

+285
-61
lines changed

17 files changed

+285
-61
lines changed

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,20 @@ Getting Started
1717
To install/update prerelease (Alpha/Beta) version version of paperspace-python, use:
1818

1919
`pip install -U --pre paperspace`
20-
21-
3. Download your api key by executing the following:
20+
3. Enable autocomplete:
21+
22+
Add following to your `.bashrc` (or `.zshrc`) to enable autocomplete anytime you activate your shell.
23+
24+
`eval $(_PAPERSPACE_PYTHON_COMPLETE=source paperspace-python)`
25+
26+
For other shell (eg. `zsh` or `fish`), use proper version of `source` (`source_zsh` and `source-fish` respectively)
27+
28+
Alternatively, you can create activation script by:
29+
30+
`(_PAPERSPACE_PYTHON_COMPLETE=source paperspace-python > ~/paperspace_complete.sh`
31+
32+
More: https://click.palletsprojects.com/en/7.x/bashcomplete/
33+
4. Download your api key by executing the following:
2234

2335
`paperspace-python login`
2436

@@ -33,7 +45,7 @@ Getting Started
3345

3446
`paperspace-python logout`
3547

36-
4. Run the sample script hello.py using Python:
48+
5. Run the sample script hello.py using Python:
3749

3850
`python hello.py`
3951

@@ -49,7 +61,7 @@ Getting Started
4961
5062
Note: the source is modified before transfer to the job cluster in order to remove imported `paperspace` references.
5163
52-
5. Use paperspace-python to run a python script remotely:
64+
6. Use paperspace-python to run a python script remotely:
5365
5466
`paperspace-python run myscript.py`
5567

paperspace/cli/cli.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import click
2+
import click_completion
23

34
from paperspace import config
45
from paperspace.cli import common
56
from paperspace.commands import login as login_commands
67

8+
click_completion.init()
9+
710

811
@click.group(cls=common.ClickGroup, **config.HELP_COLORS_DICT)
912
def cli():

paperspace/cli/common.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import getpass
22

33
import click
4+
from click import group
45
from click_didyoumean import DYMMixin
56
from click_help_colors import HelpColorsGroup
67

@@ -19,7 +20,27 @@ def del_if_value_is_none(dict_):
1920

2021

2122
class ClickGroup(DYMMixin, HelpColorsGroup):
22-
pass
23+
def group(self, *args, **kwargs):
24+
aliases = []
25+
_args = args
26+
if args and isinstance(args[0], list):
27+
# we have a list so create group aliases
28+
aliases = args[0][1:]
29+
_args = [args[0][0]] + list(args[1:])
30+
31+
if 'alias' in kwargs:
32+
aliases.append(kwargs.pop('alias'))
33+
34+
def decorator(f):
35+
cmd = group(*_args, **kwargs)(f)
36+
self.add_command(cmd)
37+
for alias in set(aliases):
38+
alias_cmd = group(alias, **kwargs)(f)
39+
self.add_command(alias_cmd)
40+
alias_cmd.commands = cmd.commands
41+
return cmd
42+
43+
return decorator
2344

2445

2546
def prompt_for_secret(prompt):

paperspace/cli/deployments.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
import click
44

5-
from paperspace import constants, client, config
5+
from paperspace import client, config
66
from paperspace.cli.cli import cli
77
from paperspace.cli.cli_types import ChoiceType
88
from paperspace.cli.common import api_key_option, del_if_value_is_none, ClickGroup
99
from paperspace.commands import deployments as deployments_commands
1010

1111

12-
@cli.group("deployments", help="Manage deployments", cls=ClickGroup)
12+
@cli.group("deployments", alias='deployment', help="Manage deployments", cls=ClickGroup)
1313
def deployments():
1414
pass
1515

@@ -22,7 +22,8 @@ def deployments():
2222
)
2323

2424
DEPLOYMENT_MACHINE_TYPES = ("G1", "G6", "G12",
25-
"K80", "P100", "V100")
25+
"K80", "P100", "GV100")
26+
2627

2728
@deployments.command("create", help="Create new deployment")
2829
@click.option(
@@ -135,4 +136,4 @@ def start_deployment(id_, api_key=None):
135136
def stop_deployment(id_, api_key=None):
136137
deployments_api = client.API(config.CONFIG_HOST, api_key=api_key)
137138
command = deployments_commands.StopDeploymentCommand(api=deployments_api)
138-
command.execute(id_)
139+
command.execute(id_)

paperspace/cli/experiments.py

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
)
1818

1919

20-
@cli.group("experiments", help="Manage experiments", cls=ClickGroup)
20+
@cli.group(["experiments", "experiment"], help="Manage experiments", cls=ClickGroup)
2121
def experiments():
2222
pass
2323

@@ -235,6 +235,13 @@ def common_experiments_create_single_node_options(f):
235235
return functools.reduce(lambda x, opt: opt(x), reversed(options), f)
236236

237237

238+
show_logs_option = click.option(
239+
"--logs/--no-logs",
240+
"show_logs",
241+
default=False,
242+
)
243+
244+
238245
@create_experiment.command(name="multinode", help="Create multi node experiment")
239246
@common_experiments_create_options
240247
@common_experiment_create_multi_node_options
@@ -259,30 +266,42 @@ def create_single_node(api_key, **kwargs):
259266
@create_and_start_experiment.command(name="multinode", help="Create and start new multi node experiment")
260267
@common_experiments_create_options
261268
@common_experiment_create_multi_node_options
262-
def create_and_start_multi_node(api_key, **kwargs):
269+
@show_logs_option
270+
@click.pass_context
271+
def create_and_start_multi_node(ctx, api_key, show_logs, **kwargs):
263272
del_if_value_is_none(kwargs)
264273
experiments_api = client.API(config.CONFIG_EXPERIMENTS_HOST, api_key=api_key)
265274
command = experiments_commands.CreateAndStartExperimentCommand(api=experiments_api)
266-
command.execute(kwargs)
275+
experiment = command.execute(kwargs)
276+
if experiment and show_logs:
277+
ctx.invoke(list_logs, experiment_id=experiment["handle"], line=0, limit=100, follow=True, api_key=api_key)
267278

268279

269280
@create_and_start_experiment.command(name="singlenode", help="Create and start new single node experiment")
270281
@common_experiments_create_options
271282
@common_experiments_create_single_node_options
272-
def create_and_start_single_node(api_key, **kwargs):
283+
@show_logs_option
284+
@click.pass_context
285+
def create_and_start_single_node(ctx, api_key, show_logs, **kwargs):
273286
kwargs["experimentType"] = constants.ExperimentType.SINGLE_NODE
274287
del_if_value_is_none(kwargs)
275288
experiments_api = client.API(config.CONFIG_EXPERIMENTS_HOST, api_key=api_key)
276289
command = experiments_commands.CreateAndStartExperimentCommand(api=experiments_api)
277-
command.execute(kwargs)
290+
experiment = command.execute(kwargs)
291+
if experiment and show_logs:
292+
ctx.invoke(list_logs, experiment_id=experiment["handle"], line=0, limit=100, follow=True, api_key=api_key)
278293

279294

280295
@experiments.command("start", help="Start experiment")
281296
@click.argument("experiment-id")
282297
@api_key_option
283-
def start_experiment(experiment_id, api_key):
298+
@show_logs_option
299+
@click.pass_context
300+
def start_experiment(ctx, experiment_id, show_logs, api_key):
284301
experiments_api = client.API(config.CONFIG_EXPERIMENTS_HOST, api_key=api_key)
285302
experiments_commands.start_experiment(experiment_id, api=experiments_api)
303+
if show_logs:
304+
ctx.invoke(list_logs, experiment_id=experiment_id, line=0, limit=100, follow=True, api_key=api_key)
286305

287306

288307
@experiments.command("stop", help="Stop experiment")
@@ -308,3 +327,34 @@ def list_experiments(project_ids, api_key):
308327
def get_experiment_details(experiment_id, api_key):
309328
experiments_api = client.API(config.CONFIG_EXPERIMENTS_HOST, api_key=api_key)
310329
experiments_commands.get_experiment_details(experiment_id, api=experiments_api)
330+
331+
332+
@experiments.command("logs", help="List experiment logs")
333+
@click.option(
334+
"--experimentId",
335+
"experiment_id",
336+
required=True
337+
)
338+
@click.option(
339+
"--line",
340+
"line",
341+
required=False,
342+
default=0
343+
)
344+
@click.option(
345+
"--limit",
346+
"limit",
347+
required=False,
348+
default=10000
349+
)
350+
@click.option(
351+
"--follow",
352+
"follow",
353+
required=False,
354+
default=False
355+
)
356+
@api_key_option
357+
def list_logs(experiment_id, line, limit, follow, api_key=None):
358+
logs_api = client.API(config.CONFIG_LOG_HOST, api_key=api_key)
359+
command = experiments_commands.ExperimentLogsCommand(api=logs_api)
360+
command.execute(experiment_id, line, limit, follow)

paperspace/cli/hyperparameters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from paperspace.commands import hyperparameters as hyperparameters_commands
1010

1111

12-
@cli.group("hyperparameters", help="Manage hyperparameters", cls=ClickGroup)
12+
@cli.group(["hyperparameters", "hyperparameter"], help="Manage hyperparameters", cls=ClickGroup)
1313
def hyperparameters_group():
1414
pass
1515

paperspace/cli/jobs.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from paperspace.commands import jobs as jobs_commands
1010

1111

12-
@cli.group("jobs", help="Manage gradient jobs", cls=ClickGroup)
12+
@cli.group(["jobs", "job"], help="Manage gradient jobs", cls=ClickGroup)
1313
def jobs_group():
1414
pass
1515

@@ -96,24 +96,45 @@ def common_jobs_create_options(f):
9696
@jobs_group.command("create", help="Create job")
9797
@common_jobs_create_options
9898
@api_key_option
99-
def create_job(api_key, **kwargs):
99+
@click.pass_context
100+
def create_job(ctx, api_key, **kwargs):
100101
del_if_value_is_none(kwargs)
101102
jobs_api = client.API(config.CONFIG_HOST, api_key=api_key)
102103
command = jobs_commands.CreateJobCommand(api=jobs_api)
103-
command.execute(kwargs)
104+
job = command.execute(kwargs)
105+
if job is not None:
106+
ctx.invoke(list_logs, job_id=job["handle"], line=0, limit=100, follow=True, api_key=api_key)
104107

105108

106-
@jobs_group.command("log", help="List job logs")
109+
@jobs_group.command("logs", help="List job logs")
107110
@click.option(
108111
"--jobId",
109112
"job_id",
110113
required=True
111114
)
115+
@click.option(
116+
"--line",
117+
"line",
118+
required=False,
119+
default=0
120+
)
121+
@click.option(
122+
"--limit",
123+
"limit",
124+
required=False,
125+
default=10000
126+
)
127+
@click.option(
128+
"--follow",
129+
"follow",
130+
required=False,
131+
default=False
132+
)
112133
@api_key_option
113-
def list_logs(job_id, api_key=None):
134+
def list_logs(job_id, line, limit, follow, api_key=None):
114135
logs_api = client.API(config.CONFIG_LOG_HOST, api_key=api_key)
115136
command = jobs_commands.JobLogsCommand(api=logs_api)
116-
command.execute(job_id)
137+
command.execute(job_id, line, limit, follow)
117138

118139

119140
@jobs_group.group("artifacts", help="Manage jobs' artifacts", cls=ClickGroup)

paperspace/cli/machines.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
)
1919

2020

21-
@cli.group("machines", help="Manage machines", cls=ClickGroup)
21+
@cli.group(["machines", "machine"], help="Manage machines", cls=ClickGroup)
2222
def machines_group():
2323
pass
2424

paperspace/cli/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from paperspace.commands import models as models_commands
77

88

9-
@cli.group("models", help="Manage models", cls=common.ClickGroup)
9+
@cli.group(["models", "model"], help="Manage models", cls=common.ClickGroup)
1010
def models_group():
1111
pass
1212

paperspace/cli/projects.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from paperspace.cli import common
55

66

7-
@cli.group("projects", help="Manage projects", cls=common.ClickGroup)
7+
@cli.group(["projects", "project"], help="Manage projects", cls=common.ClickGroup)
88
def projects_group():
99
pass
1010

paperspace/commands/__init__.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +0,0 @@
1-
from collections import OrderedDict
2-
3-
from paperspace import logger
4-
5-
6-
class CommandBase(object):
7-
def __init__(self, api=None, logger_=logger):
8-
self.api = api
9-
self.logger = logger_
10-
11-
def _print_dict_recursive(self, input_dict, indent=0, tabulator=" "):
12-
for key, val in input_dict.items():
13-
self.logger.log("%s%s:" % (tabulator * indent, key))
14-
if type(val) is dict:
15-
self._print_dict_recursive(OrderedDict(val), indent + 1)
16-
else:
17-
self.logger.log("%s%s" % (tabulator * (indent + 1), val))

paperspace/commands/common.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pydoc
2+
from collections import OrderedDict
23

34
import terminaltables
45

@@ -11,6 +12,13 @@ def __init__(self, api=None, logger_=logger):
1112
self.api = api
1213
self.logger = logger_
1314

15+
def _print_dict_recursive(self, input_dict, indent=0, tabulator=" "):
16+
for key, val in input_dict.items():
17+
self.logger.log("%s%s:" % (tabulator * indent, key))
18+
if type(val) is dict:
19+
self._print_dict_recursive(OrderedDict(val), indent + 1)
20+
else:
21+
self.logger.log("%s%s" % (tabulator * (indent + 1), val))
1422

1523
class ListCommand(CommandBase):
1624
@property

0 commit comments

Comments
 (0)