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

Commit 379715f

Browse files
committed
Add support for deployments
1 parent a90fd38 commit 379715f

File tree

12 files changed

+850
-36
lines changed

12 files changed

+850
-36
lines changed

Pipfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ twine = "*"
1919
pypandoc = "*"
2020
pytest = "*"
2121
mock = "*"
22+
coverage = "*"

paperspace/cli.py

Lines changed: 259 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
import collections
12
import functools
23
import json
34

45
import click
56

67
from paperspace import constants
7-
from paperspace.commands import experiments as experiments_commands
8+
from paperspace.commands import experiments as experiments_commands, deployments as deployments_commands
89

910

1011
class ChoiceType(click.Choice):
@@ -19,10 +20,12 @@ def convert(self, value, param, ctx):
1920
return self.type_map[value]
2021

2122

22-
MULTI_NODE_EXPERIMENT_TYPES_MAP = {
23-
"GRPC": constants.ExperimentType.GRPC_MULTI_NODE,
24-
"MPI": constants.ExperimentType.MPI_MULTI_NODE,
25-
}
23+
MULTI_NODE_EXPERIMENT_TYPES_MAP = collections.OrderedDict(
24+
(
25+
("GRPC", constants.ExperimentType.GRPC_MULTI_NODE),
26+
("MPI", constants.ExperimentType.MPI_MULTI_NODE),
27+
)
28+
)
2629

2730

2831
def json_string(val):
@@ -284,6 +287,257 @@ def list_experiments(project_handles):
284287
def get_experiment_details(experiment_handle):
285288
experiments_commands.get_experiment_details(experiment_handle)
286289

290+
287291
# TODO: delete experiment - not implemented in the api
288292
# TODO: modify experiment - not implemented in the api
289293
# TODO: create experiment template?? What is the difference between experiment and experiment template?
294+
295+
296+
DEPLOYMENT_TYPES_MAP = collections.OrderedDict(
297+
(
298+
("TFSERVING", "Tensorflow Serving on K8s"),
299+
("GRADIENT", "Gradient Jobs"),
300+
)
301+
)
302+
303+
304+
@cli.group("deployments")
305+
def deployments():
306+
pass
307+
308+
309+
@deployments.command("create")
310+
@click.option(
311+
"--deploymentType",
312+
"deploymentType",
313+
type=ChoiceType(DEPLOYMENT_TYPES_MAP, case_sensitive=False),
314+
required=True,
315+
)
316+
@click.option(
317+
"--modelId",
318+
"modelId",
319+
required=True,
320+
)
321+
@click.option(
322+
"--name",
323+
"name",
324+
required=True,
325+
)
326+
@click.option(
327+
"--tag",
328+
"tag",
329+
)
330+
@click.option(
331+
"--code",
332+
"code"
333+
)
334+
@click.option(
335+
"--cluster",
336+
"cluster",
337+
)
338+
@click.option(
339+
"--machineType",
340+
"machineType",
341+
required=True,
342+
)
343+
@click.option(
344+
"--imageUrl",
345+
"imageUrl",
346+
required=True,
347+
)
348+
@click.option(
349+
"--imageUsername",
350+
"imageUsername",
351+
)
352+
@click.option(
353+
"--imagePassword",
354+
"imagePassword",
355+
)
356+
@click.option(
357+
"--workspaceUrl",
358+
"workspaceUrl",
359+
)
360+
@click.option(
361+
"--workspaceUsername",
362+
"workspaceUsername",
363+
)
364+
@click.option(
365+
"--workspacePassword",
366+
"workspacePassword",
367+
)
368+
@click.option(
369+
"--instanceCount",
370+
"instanceCount",
371+
type=int,
372+
required=True,
373+
)
374+
@click.option(
375+
"--authToken",
376+
"authToken",
377+
)
378+
@click.option(
379+
"--oauthKey",
380+
"oauthKey",
381+
)
382+
@click.option(
383+
"--oauthSecret",
384+
"oauthSecret",
385+
)
386+
@click.option(
387+
"--serviceType",
388+
"serviceType",
389+
)
390+
@click.option(
391+
"--apiType",
392+
"apiType",
393+
)
394+
@click.option(
395+
"--ports",
396+
"ports",
397+
)
398+
def create_deployment(**kwargs):
399+
del_if_value_is_none(kwargs)
400+
command = deployments_commands.CreateDeployment()
401+
command.execute(kwargs)
402+
403+
404+
DEPLOYMENT_STATES_MAP = collections.OrderedDict(
405+
(
406+
("BUILDING", "Building"),
407+
("PROVISIONING", "Provisioning"),
408+
("STARTING", "Starting"),
409+
("RUNNING", "Running"),
410+
("STOPPING", "Stopping"),
411+
("STOPPED", "Stopped"),
412+
("ERROR", "Error"),
413+
)
414+
)
415+
416+
417+
@deployments.command("list")
418+
@click.option(
419+
"--state",
420+
"state",
421+
type=ChoiceType(DEPLOYMENT_STATES_MAP, case_sensitive=False)
422+
)
423+
def get_deployments_list(**kwargs):
424+
command = deployments_commands.ListDeployments()
425+
command.execute(kwargs)
426+
427+
428+
@deployments.command("update")
429+
@click.option(
430+
"--id",
431+
"id",
432+
required=True,
433+
)
434+
@click.option(
435+
"--name",
436+
"name",
437+
)
438+
@click.option(
439+
"--tag",
440+
"tag",
441+
)
442+
@click.option(
443+
"--params",
444+
"params",
445+
)
446+
@click.option(
447+
"--code",
448+
"code",
449+
)
450+
@click.option(
451+
"--cluster",
452+
"cluster",
453+
)
454+
@click.option(
455+
"--machineType",
456+
"machineType",
457+
)
458+
@click.option(
459+
"--imageUrl",
460+
"imageUrl",
461+
)
462+
@click.option(
463+
"--imageUsername",
464+
"imageUsername",
465+
)
466+
@click.option(
467+
"--imagePassword",
468+
"imagePassword",
469+
)
470+
@click.option(
471+
"--workspaceUrl",
472+
"workspaceUrl",
473+
)
474+
@click.option(
475+
"--workspaceUsername",
476+
"workspaceUsername",
477+
)
478+
@click.option(
479+
"--workspacePassword",
480+
"workspacePassword",
481+
)
482+
@click.option(
483+
"--instanceCount",
484+
"instanceCount",
485+
)
486+
@click.option(
487+
"--authToken",
488+
"authToken",
489+
)
490+
@click.option(
491+
"--annotations",
492+
"annotations",
493+
)
494+
@click.option(
495+
"--authToken",
496+
"authToken",
497+
)
498+
@click.option(
499+
"--oauthKey",
500+
"oauthKey",
501+
)
502+
@click.option(
503+
"--oauthSecret",
504+
"oauthSecret",
505+
)
506+
@click.option(
507+
"--serviceType",
508+
"serviceType",
509+
)
510+
@click.option(
511+
"--apiType",
512+
"apiType",
513+
)
514+
@click.option(
515+
"--ports",
516+
"ports",
517+
)
518+
def update_deployment_model(id=None, **kwargs):
519+
del_if_value_is_none(kwargs)
520+
command = deployments_commands.UpdateModelCommand()
521+
command.execute(id, kwargs)
522+
523+
524+
@deployments.command("start")
525+
@click.option(
526+
"--id",
527+
"id",
528+
required=True,
529+
)
530+
def start_deployment(id):
531+
command = deployments_commands.StartDeployment()
532+
command.execute(id)
533+
534+
535+
@deployments.command("delete")
536+
@click.option(
537+
"--id",
538+
"id",
539+
required=True,
540+
)
541+
def delete_deployment(id):
542+
command = deployments_commands.DeleteDeployment()
543+
command.execute(id)

paperspace/client.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@ def get_path(self, url):
1616
def post(self, url, json=None, params=None):
1717
path = self.get_path(url)
1818
response = requests.post(path, json=json, params=params, headers=self.headers)
19-
logger.debug("POST request sent to: {} with headers: {}".format(response.url, self.headers))
19+
logger.debug("POST request sent to: {} \n\theaders: {}\n\tjson: {}".format(response.url, self.headers, json))
2020
logger.debug("Response status code: {}".format(response.status_code))
2121
logger.debug("Response content: {}".format(response.content))
2222
return response
2323

24-
def put(self, url):
24+
def put(self, url, json=None, params=None):
2525
path = self.get_path(url)
26-
response = requests.put(path, headers=self.headers)
27-
logger.debug("PUT request sent to: {} with headers: {}".format(response.url, self.headers))
26+
response = requests.put(path, json=json, params=params, headers=self.headers)
27+
logger.debug("PUT request sent to: {} \n\theaders: {}\n\tjson: {}".format(response.url, self.headers, json))
2828
logger.debug("Response status code: {}".format(response.status_code))
2929
logger.debug("Response content: {}".format(response.content))
3030
return response
3131

32-
def get(self, url, params=None):
32+
def get(self, url, json=None, params=None):
3333
path = self.get_path(url)
34-
response = requests.get(path, params=params, headers=self.headers)
35-
logger.debug("GET request sent to: {} with headers: {}".format(response.url, self.headers))
34+
response = requests.get(path, params=params, headers=self.headers, json=json)
35+
logger.debug("GET request sent to: {} \n\theaders: {}\n\tjson: {}".format(response.url, self.headers, json))
3636
logger.debug("Response status code: {}".format(response.status_code))
3737
logger.debug("Response content: {}".format(response.content))
3838
return response

0 commit comments

Comments
 (0)