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

Commit cab84b8

Browse files
committed
Merge branch 'development' of github.com:Paperspace/paperspace-python into PS-9868
# Conflicts: # Pipfile # Pipfile.lock # paperspace/cli/cli.py # setup.py # tests/example_responses.py
2 parents ce42376 + e640ebe commit cab84b8

25 files changed

+1999
-1036
lines changed

Pipfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ six = "*"
1313
gradient-statsd = "*"
1414
click = "*"
1515
terminaltables = "*"
16+
click-didyoumean = "*"
17+
click-help-colors = "*"
1618
colorclass = "*"
1719
tox = "*"
1820

Pipfile.lock

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Paperspace Python
22
=================
33

4-
Release 0.1.0a0
4+
Release 0.1.0
55

66
See [releasenotes.md](https://github.com/Paperspace/paperspace-python/blob/master/releasenotes.md) for details on the current release, as well as release history.
77

paperspace/cli/cli.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
import click
55

66
from paperspace import constants, client, config
7+
from paperspace.cli import common
78
from paperspace.cli.common import api_key_option, del_if_value_is_none
89
from paperspace.cli.jobs import jobs_group
910
from paperspace.cli.logs import logs_group
11+
from paperspace.cli.models import models_group
1012
from paperspace.cli.projects import projects_group
1113
from paperspace.cli.cli_types import ChoiceType, json_string
1214
from paperspace.cli.validators import validate_mutually_exclusive, validate_email
@@ -21,22 +23,22 @@
2123
)
2224

2325

24-
@click.group()
26+
@click.group(cls=common.ClickGroup, **config.HELP_COLORS_DICT)
2527
def cli():
2628
pass
2729

2830

29-
@cli.group("experiments", help="Manage experiments")
31+
@cli.group("experiments", help="Manage experiments", cls=common.ClickGroup)
3032
def experiments():
3133
pass
3234

3335

34-
@experiments.group("create", help="Create new experiment")
36+
@experiments.group("create", help="Create new experiment", cls=common.ClickGroup)
3537
def create_experiment():
3638
pass
3739

3840

39-
@experiments.group(name="createAndStart", help="Create and start new experiment")
41+
@experiments.group(name="createAndStart", help="Create and start new experiment", cls=common.ClickGroup)
4042
def create_and_start_experiment():
4143
pass
4244

@@ -328,7 +330,7 @@ def get_experiment_details(experiment_handle, api_key):
328330
)
329331

330332

331-
@cli.group("deployments", help="Manage deployments")
333+
@cli.group("deployments", help="Manage deployments", cls=common.ClickGroup)
332334
def deployments():
333335
pass
334336

@@ -401,12 +403,22 @@ def create_deployment(api_key=None, **kwargs):
401403
type=ChoiceType(DEPLOYMENT_STATES_MAP, case_sensitive=False),
402404
help="Filter by deployment state",
403405
)
406+
@click.option(
407+
"--projectId",
408+
"projectId",
409+
help="Use to filter by project ID",
410+
)
411+
@click.option(
412+
"--modelId",
413+
"modelId",
414+
help="Use to filter by project ID",
415+
)
404416
@api_key_option
405-
def get_deployments_list(api_key=None, **kwargs):
406-
del_if_value_is_none(kwargs)
417+
def get_deployments_list(api_key=None, **filters):
418+
del_if_value_is_none(filters)
407419
deployments_api = client.API(config.CONFIG_HOST, api_key=api_key)
408420
command = deployments_commands.ListDeploymentsCommand(api=deployments_api)
409-
command.execute(kwargs)
421+
command.execute(filters)
410422

411423

412424
@deployments.command("update", help="Update deployment properties")
@@ -446,7 +458,7 @@ def get_deployments_list(api_key=None, **kwargs):
446458
def update_deployment_model(id_, api_key, **kwargs):
447459
del_if_value_is_none(kwargs)
448460
deployments_api = client.API(config.CONFIG_HOST, api_key=api_key)
449-
command = deployments_commands.UpdateModelCommand(api=deployments_api)
461+
command = deployments_commands.UpdateDeploymentCommand(api=deployments_api)
450462
command.execute(id_, kwargs)
451463

452464

@@ -487,7 +499,7 @@ def delete_deployment(id_, api_key=None):
487499
)
488500

489501

490-
@cli.group("machines", help="Manage machines")
502+
@cli.group("machines", help="Manage machines", cls=common.ClickGroup)
491503
def machines_group():
492504
pass
493505

@@ -1055,6 +1067,7 @@ def version():
10551067

10561068
cli.add_command(jobs_group)
10571069
cli.add_command(projects_group)
1070+
cli.add_command(models_group)
10581071
cli.add_command(logs_group)
10591072

10601073

paperspace/cli/common.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import click
2+
from click_didyoumean import DYMMixin
3+
from click_help_colors import HelpColorsGroup
24

35
api_key_option = click.option(
46
"--apiKey",
@@ -11,4 +13,8 @@ def del_if_value_is_none(dict_):
1113
"""Remove all elements with value == None"""
1214
for key, val in list(dict_.items()):
1315
if val is None:
14-
del dict_[key]
16+
del dict_[key]
17+
18+
19+
class ClickGroup(DYMMixin, HelpColorsGroup):
20+
pass

paperspace/cli/jobs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from paperspace.commands import jobs as jobs_commands
66

77

8-
@click.group("jobs", help="Manage gradient jobs")
8+
@click.group("jobs", help="Manage gradient jobs", cls=common.ClickGroup)
99
def jobs_group():
1010
pass
1111

paperspace/cli/models.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import click
2+
3+
from paperspace import client, config
4+
from paperspace.cli import common
5+
from paperspace.commands import models as models_commands
6+
7+
8+
@click.group("models", help="Manage models", cls=common.ClickGroup)
9+
def models_group():
10+
pass
11+
12+
13+
@models_group.command("list", help="List models with optional filtering")
14+
@click.option(
15+
"--experimentId",
16+
"experimentId",
17+
help="Use to filter by experiment ID",
18+
)
19+
@click.option(
20+
"--projectId",
21+
"projectId",
22+
help="Use to filter by project ID",
23+
)
24+
@common.api_key_option
25+
def list_models(api_key, **filters):
26+
common.del_if_value_is_none(filters)
27+
models_api = client.API(config.CONFIG_HOST, api_key=api_key)
28+
command = models_commands.ListModelsCommand(api=models_api)
29+
command.execute(filters)

paperspace/cli/projects.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from . import common
66

77

8-
@click.group("projects", help="Manage projects")
8+
@click.group("projects", help="Manage projects", cls=common.ClickGroup)
99
def projects_group():
1010
pass
1111

paperspace/commands/deployments.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def _log_message(self, response, success_msg_template, error_msg):
1919
j = response.json()
2020
handle = j["deployment"]
2121
except (ValueError, KeyError):
22-
self.logger.log(success_msg_template)
22+
self.logger.error(success_msg_template)
2323
else:
2424
msg = success_msg_template.format(**handle)
2525
self.logger.log(msg)
@@ -28,7 +28,7 @@ def _log_message(self, response, success_msg_template, error_msg):
2828
data = response.json()
2929
self.logger.log_error_response(data)
3030
except ValueError:
31-
self.logger.log(error_msg)
31+
self.logger.error(error_msg)
3232

3333

3434
class CreateDeploymentCommand(_DeploymentCommandBase):
@@ -40,25 +40,28 @@ def execute(self, kwargs):
4040

4141

4242
class ListDeploymentsCommand(_DeploymentCommandBase):
43-
def execute(self, kwargs):
44-
json_ = self._get_request_json(kwargs)
43+
def execute(self, filters=None):
44+
json_ = self._get_request_json(filters)
4545
response = self.api.get("/deployments/getDeploymentList/", json=json_)
4646

4747
try:
48+
data = response.json()
49+
if not response.ok:
50+
self.logger.log_error_response(data)
51+
return
4852
deployments = self._get_deployments_list(response)
4953
except (ValueError, KeyError) as e:
50-
self.logger.log("Error while parsing response data: {}".format(e))
54+
self.logger.error("Error while parsing response data: {}".format(e))
5155
else:
5256
self._log_deployments_list(deployments)
5357

5458
@staticmethod
55-
def _get_request_json(kwargs):
56-
state = kwargs.get("state")
57-
if not state:
59+
def _get_request_json(filters):
60+
if not filters:
5861
return None
5962

60-
params = {"filter": {"where": {"and": [{"state": state}]}}}
61-
return params
63+
json_ = {"filter": {"where": {"and": [filters]}}}
64+
return json_
6265

6366
@staticmethod
6467
def _get_deployments_list(response):
@@ -71,7 +74,7 @@ def _get_deployments_list(response):
7174

7275
def _log_deployments_list(self, deployments):
7376
if not deployments:
74-
self.logger.log("No deployments found")
77+
self.logger.warning("No deployments found")
7578
else:
7679
table_str = self._make_deployments_list_table(deployments)
7780
if len(table_str.splitlines()) > get_terminal_lines():
@@ -95,13 +98,13 @@ def _make_deployments_list_table(deployments):
9598
return table_string
9699

97100

98-
class UpdateModelCommand(_DeploymentCommandBase):
99-
def execute(self, model_id, kwargs):
101+
class UpdateDeploymentCommand(_DeploymentCommandBase):
102+
def execute(self, deployment_id, kwargs):
100103
if not kwargs:
101104
self.logger.log("No parameters to update were given. Use --help for more information.")
102105
return
103106

104-
json_ = {"id": model_id,
107+
json_ = {"id": deployment_id,
105108
"upd": kwargs}
106109
response = self.api.post("/deployments/updateDeployment/", json=json_)
107110
self._log_message(response,
@@ -110,8 +113,8 @@ def execute(self, model_id, kwargs):
110113

111114

112115
class StartDeploymentCommand(_DeploymentCommandBase):
113-
def execute(self, model_id):
114-
json_ = {"id": model_id,
116+
def execute(self, deployment_id):
117+
json_ = {"id": deployment_id,
115118
"isRunning": True}
116119
response = self.api.post("/deployments/updateDeployment/", json=json_)
117120
self._log_message(response,
@@ -120,8 +123,8 @@ def execute(self, model_id):
120123

121124

122125
class DeleteDeploymentCommand(_DeploymentCommandBase):
123-
def execute(self, model_id):
124-
json_ = {"id": model_id,
126+
def execute(self, deployment_id):
127+
json_ = {"id": deployment_id,
125128
"upd": {"isDeleted": True}}
126129
response = self.api.post("/deployments/updateDeployment/", json=json_)
127130
self._log_message(response,

paperspace/commands/experiments.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def _log_create_experiment(response, success_msg_template, error_msg, logger_=lo
2020
data = response.json()
2121
logger_.log_error_response(data)
2222
except ValueError:
23-
logger_.log(error_msg)
23+
logger_.error(error_msg)
2424

2525

2626
def create_experiment(json_, api=experiments_api):
@@ -56,21 +56,20 @@ def __init__(self, api=experiments_api, logger_=logger):
5656
self.logger = logger_
5757

5858
def execute(self, project_handles=None):
59+
project_handles = project_handles or []
5960
params = self._get_query_params(project_handles)
6061
response = self.api.get("/experiments/", params=params)
6162

6263
try:
6364
experiments = self._get_experiments_list(response, bool(project_handles))
6465
except (ValueError, KeyError) as e:
65-
self.logger.log("Error while parsing response data: {}".format(e))
66+
self.logger.error("Error while parsing response data: {}".format(e))
6667
else:
6768
self._log_experiments_list(experiments)
6869

6970
@staticmethod
7071
def _get_query_params(project_handles):
71-
# TODO: change to limit: -1 when PS-9535 is deployed to production
72-
# to list all experiments
73-
params = {"limit": 1000000}
72+
params = {"limit": -1} # so the API sends back full list without pagination
7473
for i, handle in enumerate(project_handles):
7574
key = "projectHandle[{}]".format(i)
7675
params[key] = handle
@@ -107,7 +106,7 @@ def _get_experiments_list(response, filtered=False):
107106

108107
def _log_experiments_list(self, experiments):
109108
if not experiments:
110-
self.logger.log("No experiments found")
109+
self.logger.warning("No experiments found")
111110
else:
112111
table_str = self._make_experiments_list_table(experiments)
113112
if len(table_str.splitlines()) > get_terminal_lines():
@@ -176,7 +175,6 @@ def get_experiment_details(experiment_handle, api=experiments_api):
176175
experiment = response.json()["data"]
177176
details = _make_details_table(experiment)
178177
except (ValueError, KeyError) as e:
179-
logger.log("Error parsing response data")
180-
logger.debug(e)
178+
logger.error("Error parsing response data")
181179

182180
log_response(response, details, "Unknown error while retrieving details of the experiment")

0 commit comments

Comments
 (0)