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

Commit b2717c7

Browse files
BartoszCkikossak
authored andcommitted
Add jobs support starting with job delete
1 parent 53a7465 commit b2717c7

File tree

10 files changed

+162
-107
lines changed

10 files changed

+162
-107
lines changed

paperspace/cli/__init__.py

Whitespace-only changes.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import click
77

88
from paperspace import constants, client, config
9+
from paperspace.cli.jobs.commands import jobs_group
910
from paperspace.commands import experiments as experiments_commands, deployments as deployments_commands, \
1011
machines as machines_commands, login as login_commands
1112

@@ -1109,3 +1110,6 @@ def logout():
11091110
def version():
11101111
command = login_commands.ShowVersionCommand()
11111112
command.execute()
1113+
1114+
1115+
cli.add_command(jobs_group)

paperspace/cli/jobs/__init__.py

Whitespace-only changes.

paperspace/cli/jobs/commands.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import click
2+
3+
from paperspace import client, config
4+
from paperspace.commands import jobs as jobs_commands
5+
6+
7+
@click.group("jobs", help="Manage gradient jobs")
8+
def jobs_group():
9+
pass
10+
11+
12+
@jobs_group.command("delete", help="Delete job")
13+
@click.option(
14+
"--jobId",
15+
"job_id",
16+
required=True,
17+
)
18+
def delete_job(job_id, api_key=None):
19+
jobs_api = client.API(config.CONFIG_HOST, api_key=api_key)
20+
command = jobs_commands.DeleteJobCommand(api=jobs_api)
21+
command.execute(job_id)

paperspace/commands/jobs.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from paperspace.commands import CommandBase
2+
3+
4+
class _JobsCommandBase(CommandBase):
5+
def _log_message(self, response, success_msg_template, error_msg):
6+
if response.ok:
7+
try:
8+
handle = response.json()
9+
except (ValueError, KeyError):
10+
self.logger.log(success_msg_template)
11+
else:
12+
msg = success_msg_template.format(**handle)
13+
self.logger.log(msg)
14+
else:
15+
try:
16+
data = response.json()
17+
self.logger.log_error_response(data)
18+
except ValueError:
19+
self.logger.log(error_msg)
20+
21+
22+
class DeleteJobCommand(_JobsCommandBase):
23+
def execute(self, job_id):
24+
url = "/jobs/{}/destroy/".format(job_id)
25+
response = self.api.post(url)
26+
self._log_message(response,
27+
"Job deleted",
28+
"Unknown error while deleting job")

paperspace/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
import sys
33

4-
from .cli import cli
4+
from paperspace.cli.cli import cli
55
from .jobs import run, print_json_pretty
66
from .login import set_apikey
77
from .version import version

tests/functional/test_deployments.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from click.testing import CliRunner
33

44
import paperspace.client
5-
from paperspace import cli
5+
from paperspace.cli import cli
66
from paperspace.commands import deployments as deployments_commands
77
from tests import example_responses, MockResponse
88

@@ -47,7 +47,7 @@ class TestDeploymentsCreate(object):
4747
RESPONSE_CONTENT_404_MODEL_NOT_FOUND = b'{"error":{"name":"Error","status":404,"message":"Unable to find model"}}\n'
4848
EXPECTED_STDOUT_MODEL_NOT_FOUND = "Unable to find model\n"
4949

50-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
50+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
5151
def test_should_send_proper_data_and_print_message_when_create_deployment_with_basic_options(self, post_patched):
5252
post_patched.return_value = MockResponse(self.RESPONSE_JSON_200, 200, "fake content")
5353

@@ -61,7 +61,7 @@ def test_should_send_proper_data_and_print_message_when_create_deployment_with_b
6161
assert result.output == self.EXPECTED_STDOUT
6262
assert result.exit_code == 0
6363

64-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
64+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
6565
def test_should_send_different_api_key_when_api_key_parameter_was_used(self, post_patched):
6666
post_patched.return_value = MockResponse(self.RESPONSE_JSON_200, 200, "fake content")
6767

@@ -75,7 +75,7 @@ def test_should_send_different_api_key_when_api_key_parameter_was_used(self, pos
7575
assert result.output == self.EXPECTED_STDOUT
7676
assert result.exit_code == 0
7777

78-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
78+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
7979
def test_should_send_proper_data_and_print_message_when_create_wrong_model_id_was_given(self, post_patched):
8080
post_patched.return_value = MockResponse(self.RESPONSE_JSON_404_MODEL_NOT_FOUND, 404,
8181
self.RESPONSE_CONTENT_404_MODEL_NOT_FOUND)
@@ -116,7 +116,7 @@ class TestDeploymentsList(object):
116116
+-----------+-----------------+----------------------------------------------------------------------------------+---------------+---------------------------+
117117
"""
118118

119-
@mock.patch("paperspace.cli.deployments_commands.client.requests.get")
119+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.get")
120120
def test_should_send_get_request_and_print_list_of_deployments(self, get_patched):
121121
get_patched.return_value = MockResponse(self.LIST_JSON, 200, "fake content")
122122

@@ -129,7 +129,7 @@ def test_should_send_get_request_and_print_list_of_deployments(self, get_patched
129129
params=None)
130130
assert result.output == self.DETAILS_STDOUT
131131

132-
@mock.patch("paperspace.cli.deployments_commands.client.requests.get")
132+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.get")
133133
def test_should_send_get_request_with_custom_api_key_when_api_key_parameter_was_provided(self, get_patched):
134134
get_patched.return_value = MockResponse(self.LIST_JSON, 200, "fake content")
135135

@@ -142,8 +142,8 @@ def test_should_send_get_request_with_custom_api_key_when_api_key_parameter_was_
142142
params=None)
143143
assert result.output == self.DETAILS_STDOUT
144144

145-
@mock.patch("paperspace.cli.deployments_commands.pydoc")
146-
@mock.patch("paperspace.cli.deployments_commands.client.requests.get")
145+
@mock.patch("paperspace.cli.cli.deployments_commands.pydoc")
146+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.get")
147147
def test_should_send_get_request_and_paginate_list_when_output_table_len_is_gt_lines_in_terminal(self, get_patched,
148148
pydoc_patched):
149149
list_json = {"deploymentList": self.LIST_JSON["deploymentList"] * 40}
@@ -159,7 +159,7 @@ def test_should_send_get_request_and_paginate_list_when_output_table_len_is_gt_l
159159
pydoc_patched.pager.assert_called_once()
160160
assert result.exit_code == 0
161161

162-
@mock.patch("paperspace.cli.deployments_commands.client.requests.get")
162+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.get")
163163
def test_should_send_get_request_and_print_list_of_deployments_filtered_by_state(self, get_patched):
164164
get_patched.return_value = MockResponse(self.LIST_JSON, 200, "fake content")
165165

@@ -172,7 +172,7 @@ def test_should_send_get_request_and_print_list_of_deployments_filtered_by_state
172172
params=None)
173173
assert result.output == self.DETAILS_STDOUT
174174

175-
@mock.patch("paperspace.cli.deployments_commands.client.requests.get")
175+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.get")
176176
def test_should_send_get_request_and_print_list_of_deployments_filtered_with_state_but_none_found(
177177
self, get_patched):
178178
get_patched.return_value = MockResponse(self.LIST_WITH_FILTER_RESPONSE_JSON_WHEN_NO_DEPLOYMENTS_FOUND, 200,
@@ -212,7 +212,7 @@ class TestDeploymentsUpdate(object):
212212
RESPONSE_JSON_400 = {"error": {"name": "Error", "status": 400, "message": "Unable to access deployment"}}
213213
EXPECTED_STDOUT_WITH_WRONG_ID = "Unable to access deployment\n"
214214

215-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
215+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
216216
def test_should_send_proper_data_and_print_message_when_update_deployment(self, post_patched):
217217
post_patched.return_value = MockResponse(self.RESPONSE_JSON_200, 200, "fake content")
218218

@@ -226,7 +226,7 @@ def test_should_send_proper_data_and_print_message_when_update_deployment(self,
226226
assert result.output == self.EXPECTED_STDOUT
227227
assert result.exit_code == 0
228228

229-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
229+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
230230
def test_should_send_proper_data_with_custom_api_key_when_api_key_parameter_was_provided(self, post_patched):
231231
post_patched.return_value = MockResponse(self.RESPONSE_JSON_200, 200, "fake content")
232232

@@ -240,7 +240,7 @@ def test_should_send_proper_data_with_custom_api_key_when_api_key_parameter_was_
240240
assert result.output == self.EXPECTED_STDOUT
241241
assert result.exit_code == 0
242242

243-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
243+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
244244
def test_should_send_proper_data_and_print_message_when_update_deployment_used_with_wrong_id(self, post_patched):
245245
post_patched.return_value = MockResponse(self.RESPONSE_JSON_400, 400, "fake content")
246246

@@ -262,7 +262,7 @@ class TestStartDeployment(object):
262262
REQUEST_JSON = {"isRunning": True, "id": u"some_id"}
263263
EXPECTED_STDOUT = "Deployment started\n"
264264

265-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
265+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
266266
def test_should_send_proper_data_and_print_message_when_deployments_start_was_used(self, post_patched):
267267
post_patched.return_value = MockResponse(None, 204, "fake content")
268268

@@ -295,7 +295,7 @@ class TestDeleteDeployment(object):
295295
RESPONSE_JSON_400 = {"error": {"name": "Error", "status": 400, "message": "Unable to access deployment"}}
296296
EXPECTED_STDOUT_WITH_WRONG_ID = "Unable to access deployment\n"
297297

298-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
298+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
299299
def test_should_send_proper_data_and_print_message_when_deployments_delete_was_used(self, post_patched):
300300
post_patched.return_value = MockResponse(None, 204, "fake content")
301301

@@ -309,7 +309,7 @@ def test_should_send_proper_data_and_print_message_when_deployments_delete_was_u
309309
assert result.output == self.EXPECTED_STDOUT
310310
assert result.exit_code == 0
311311

312-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
312+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
313313
def test_should_send_proper_data_with_custom_api_key_when_api_key_parameter_was_provided(self, post_patched):
314314
post_patched.return_value = MockResponse(None, 204, "fake content")
315315

@@ -323,7 +323,7 @@ def test_should_send_proper_data_with_custom_api_key_when_api_key_parameter_was_
323323
assert result.output == self.EXPECTED_STDOUT
324324
assert result.exit_code == 0
325325

326-
@mock.patch("paperspace.cli.deployments_commands.client.requests.post")
326+
@mock.patch("paperspace.cli.cli.deployments_commands.client.requests.post")
327327
def test_should_send_proper_data_and_print_message_when_deployments_delete_used_with_wrong_id(self, post_patched):
328328
post_patched.return_value = MockResponse(self.RESPONSE_JSON_400, 400, "fake content")
329329

tests/functional/test_experiments.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from click.testing import CliRunner
33

44
import paperspace.client
5-
from paperspace import cli, constants
5+
from paperspace import constants
6+
from paperspace.cli import cli
67
from tests import example_responses, MockResponse
78

89

@@ -76,7 +77,7 @@ class TestExperimentsCreateSingleNode(object):
7677
RESPONSE_CONTENT_404_PROJECT_NOT_FOUND = b'{"details":{"handle":"wrong_handle"},"error":"Project not found"}\n'
7778
EXPECTED_STDOUT_PROJECT_NOT_FOUND = "Project not found\nhandle: wrong_handle\n"
7879

79-
@mock.patch("paperspace.cli.client.requests.post")
80+
@mock.patch("paperspace.cli.cli.client.requests.post")
8081
def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_basic_options(self,
8182
post_patched):
8283
post_patched.return_value = MockResponse(self.RESPONSE_JSON_200, 200, self.RESPONSE_CONTENT_200)
@@ -91,7 +92,7 @@ def test_should_send_proper_data_and_print_message_when_create_experiment_was_ru
9192
assert result.output == self.EXPECTED_STDOUT
9293
assert result.exit_code == 0
9394

94-
@mock.patch("paperspace.cli.client.requests.post")
95+
@mock.patch("paperspace.cli.cli.client.requests.post")
9596
def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_full_options(self,
9697
post_patched):
9798
post_patched.return_value = MockResponse(self.RESPONSE_JSON_200, 200, self.RESPONSE_CONTENT_200)
@@ -107,7 +108,7 @@ def test_should_send_proper_data_and_print_message_when_create_experiment_was_ru
107108
assert result.exit_code == 0
108109
assert self.EXPECTED_HEADERS_WITH_CHANGED_API_KEY["X-API-Key"] == "some_key"
109110

110-
@mock.patch("paperspace.cli.client.requests.post")
111+
@mock.patch("paperspace.cli.cli.client.requests.post")
111112
def test_should_send_proper_data_and_print_message_when_create_wrong_project_handle_was_given(self, post_patched):
112113
post_patched.return_value = MockResponse(self.RESPONSE_JSON_404_PROJECT_NOT_FOUND, 404,
113114
self.RESPONSE_CONTENT_404_PROJECT_NOT_FOUND)
@@ -219,7 +220,7 @@ class TestExperimentsCreateMultiNode(object):
219220
RESPONSE_CONTENT_200 = b'{"handle":"sadkfhlskdjh","message":"success"}\n'
220221
EXPECTED_STDOUT = "New experiment created with handle: sadkfhlskdjh\n"
221222

222-
@mock.patch("paperspace.cli.client.requests.post")
223+
@mock.patch("paperspace.cli.cli.client.requests.post")
223224
def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_basic_options(self,
224225
post_patched):
225226
post_patched.return_value = MockResponse(self.RESPONSE_JSON_200, 200, self.RESPONSE_CONTENT_200)
@@ -234,7 +235,7 @@ def test_should_send_proper_data_and_print_message_when_create_experiment_was_ru
234235
assert result.output == self.EXPECTED_STDOUT
235236
assert result.exit_code == 0
236237

237-
@mock.patch("paperspace.cli.client.requests.post")
238+
@mock.patch("paperspace.cli.cli.client.requests.post")
238239
def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_full_options(self,
239240
post_patched):
240241
post_patched.return_value = MockResponse(self.RESPONSE_JSON_200, 200, self.RESPONSE_CONTENT_200)
@@ -506,7 +507,7 @@ class TestExperimentDetail(object):
506507
+---------------------+----------------+
507508
"""
508509

509-
@mock.patch("paperspace.cli.client.requests.get")
510+
@mock.patch("paperspace.cli.cli.client.requests.get")
510511
def test_should_send_get_request_and_print_single_node_experiment_details_in_a_table(self, get_patched):
511512
get_patched.return_value = MockResponse(self.SINGLE_NODE_RESPONSE_JSON, 200, "fake content")
512513

@@ -522,7 +523,7 @@ def test_should_send_get_request_and_print_single_node_experiment_details_in_a_t
522523
assert result.exit_code == 0
523524
assert self.EXPECTED_HEADERS["X-API-Key"] != "some_key"
524525

525-
@mock.patch("paperspace.cli.client.requests.get")
526+
@mock.patch("paperspace.cli.cli.client.requests.get")
526527
def test_should_send_get_request_and_print_multi_node_experiment_details_in_a_table(self, get_patched):
527528
get_patched.return_value = MockResponse(self.MULTI_NODE_DETAILS_JSON, 200, "fake content")
528529

@@ -537,7 +538,7 @@ def test_should_send_get_request_and_print_multi_node_experiment_details_in_a_ta
537538
assert result.output == self.MULTI_NODE_DETAILS_STDOUT
538539
assert result.exit_code == 0
539540

540-
@mock.patch("paperspace.cli.client.requests.get")
541+
@mock.patch("paperspace.cli.cli.client.requests.get")
541542
def test_should_send_get_request_and_print_request_content_when_response_data_was_malformed(self, get_patched):
542543
get_patched.return_value = MockResponse({}, 200, "fake content")
543544
g = """Error parsing response data
@@ -736,7 +737,7 @@ class TestExperimentList(object):
736737
+---------------+---------------+---------+
737738
"""
738739

739-
@mock.patch("paperspace.cli.client.requests.get")
740+
@mock.patch("paperspace.cli.cli.client.requests.get")
740741
def test_should_send_get_request_and_print_list_of_experiments(self, get_patched):
741742
get_patched.return_value = MockResponse(self.LIST_JSON, 200, "fake content")
742743

@@ -751,8 +752,8 @@ def test_should_send_get_request_and_print_list_of_experiments(self, get_patched
751752
assert result.output == self.DETAILS_STDOUT
752753
assert self.EXPECTED_HEADERS["X-API-Key"] != "some_key"
753754

754-
@mock.patch("paperspace.cli.experiments_commands.pydoc")
755-
@mock.patch("paperspace.cli.client.requests.get")
755+
@mock.patch("paperspace.cli.cli.experiments_commands.pydoc")
756+
@mock.patch("paperspace.cli.cli.client.requests.get")
756757
def test_should_send_get_request_and_paginate_list_when_output_table_len_is_gt_lines_in_terminal(self, get_patched,
757758
pydoc_patched):
758759
list_json = {"data": self.LIST_JSON["data"] * 40}
@@ -769,7 +770,7 @@ def test_should_send_get_request_and_paginate_list_when_output_table_len_is_gt_l
769770
pydoc_patched.pager.assert_called_once()
770771
assert result.exit_code == 0
771772

772-
@mock.patch("paperspace.cli.client.requests.get")
773+
@mock.patch("paperspace.cli.cli.client.requests.get")
773774
def test_should_send_get_request_and_print_list_of_experiments_filtered_with_two_projects(self, get_patched):
774775
get_patched.return_value = MockResponse(example_responses.LIST_OF_EXPERIMENTS_FILTERED_WITH_TWO_PROJECTS, 200,
775776
"fake content")
@@ -786,7 +787,7 @@ def test_should_send_get_request_and_print_list_of_experiments_filtered_with_two
786787

787788
assert result.output == example_responses.LIST_OF_EXPERIMENTS_FILTERED_WITH_TWO_PROJECTS_STDOUT
788789

789-
@mock.patch("paperspace.cli.client.requests.get")
790+
@mock.patch("paperspace.cli.cli.client.requests.get")
790791
def test_should_send_get_request_and_print_list_of_experiments_filtered_with_two_projects_but_none_found(
791792
self, get_patched):
792793
get_patched.return_value = MockResponse(example_responses.LIST_OF_EXPERIMENTS_FILTERED_BUT_NONE_FOUND, 200,
@@ -815,7 +816,7 @@ class TestStartExperiment(object):
815816
RESPONSE_JSON = {"message": "success"}
816817
START_STDOUT = "Experiment started\n"
817818

818-
@mock.patch("paperspace.cli.client.requests.put")
819+
@mock.patch("paperspace.cli.cli.client.requests.put")
819820
def test_should_send_put_request_and_print_confirmation(self, put_patched):
820821
put_patched.return_value = MockResponse(self.RESPONSE_JSON, 200, "fake content")
821822
expected_headers = paperspace.client.default_headers.copy()
@@ -830,7 +831,7 @@ def test_should_send_put_request_and_print_confirmation(self, put_patched):
830831

831832
assert result.output == self.START_STDOUT
832833

833-
@mock.patch("paperspace.cli.client.requests.put")
834+
@mock.patch("paperspace.cli.cli.client.requests.put")
834835
def test_should_send_put_request_with_changed_api_key_when_api_key_option_was_provided(self, put_patched):
835836
put_patched.return_value = MockResponse(self.RESPONSE_JSON, 200, "fake content")
836837

0 commit comments

Comments
 (0)