lightning-sdk 0.1.36__py3-none-any.whl → 0.1.37__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. lightning_sdk/__init__.py +1 -1
  2. lightning_sdk/ai_hub.py +20 -11
  3. lightning_sdk/cli/entrypoint.py +2 -2
  4. lightning_sdk/cli/models.py +45 -15
  5. lightning_sdk/cli/run.py +72 -0
  6. lightning_sdk/job/base.py +48 -20
  7. lightning_sdk/job/job.py +21 -11
  8. lightning_sdk/job/v1.py +9 -9
  9. lightning_sdk/job/v2.py +6 -6
  10. lightning_sdk/lightning_cloud/openapi/models/create_deployment_request_defines_a_spec_for_the_job_that_allows_for_autoscaling_jobs.py +27 -1
  11. lightning_sdk/lightning_cloud/openapi/models/deployments_id_body.py +27 -1
  12. lightning_sdk/lightning_cloud/openapi/models/v1_checkbox.py +29 -3
  13. lightning_sdk/lightning_cloud/openapi/models/v1_deployment.py +27 -1
  14. lightning_sdk/lightning_cloud/openapi/models/v1_google_cloud_direct_v1.py +1 -27
  15. lightning_sdk/lightning_cloud/openapi/models/v1_input.py +29 -3
  16. lightning_sdk/lightning_cloud/openapi/models/v1_job.py +27 -1
  17. lightning_sdk/lightning_cloud/openapi/models/v1_select.py +29 -3
  18. lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +79 -1
  19. {lightning_sdk-0.1.36.dist-info → lightning_sdk-0.1.37.dist-info}/METADATA +1 -1
  20. {lightning_sdk-0.1.36.dist-info → lightning_sdk-0.1.37.dist-info}/RECORD +24 -23
  21. {lightning_sdk-0.1.36.dist-info → lightning_sdk-0.1.37.dist-info}/LICENSE +0 -0
  22. {lightning_sdk-0.1.36.dist-info → lightning_sdk-0.1.37.dist-info}/WHEEL +0 -0
  23. {lightning_sdk-0.1.36.dist-info → lightning_sdk-0.1.37.dist-info}/entry_points.txt +0 -0
  24. {lightning_sdk-0.1.36.dist-info → lightning_sdk-0.1.37.dist-info}/top_level.txt +0 -0
lightning_sdk/__init__.py CHANGED
@@ -27,5 +27,5 @@ __all__ = [
27
27
  "AIHub",
28
28
  ]
29
29
 
30
- __version__ = "0.1.36"
30
+ __version__ = "0.1.37"
31
31
  _check_version_and_prompt_upgrade(__version__)
lightning_sdk/ai_hub.py CHANGED
@@ -15,8 +15,17 @@ class AIHub:
15
15
  """An interface to interact with the AI Hub.
16
16
 
17
17
  Example:
18
- ai_hub = AIHub()
19
- api_list = ai_hub.list_apis()
18
+ from lightning_sdk import AIHub
19
+ hub = AIHub()
20
+
21
+ # List public API templates
22
+ api_list = hub.list_apis()
23
+
24
+ # Get detailed information about an API template
25
+ api_info = hub.api_info("temp_xxxx")
26
+
27
+ # Deploy an API template
28
+ deployment = hub.deploy("temp_xxxx")
20
29
  """
21
30
 
22
31
  def __init__(self) -> None:
@@ -28,7 +37,7 @@ class AIHub:
28
37
 
29
38
  Example:
30
39
  ai_hub = AIHub()
31
- api_info = ai_hub.api_info("api_12345")
40
+ api_info = ai_hub.api_info("temp_xxxx")
32
41
 
33
42
  Args:
34
43
  api_id: The ID of the API for which information is requested.
@@ -70,8 +79,11 @@ class AIHub:
70
79
  },
71
80
  }
72
81
 
73
- def list_apis(self, search: Optional[str] = None) -> List[Dict[str, str]]:
74
- """Get a list of AI Hub API templates.
82
+ def list_apis(
83
+ self,
84
+ search: Optional[str] = None,
85
+ ) -> List[Dict[str, str]]:
86
+ """Get a list of public AI Hub API templates.
75
87
 
76
88
  Example:
77
89
  ai_hub = AIHub()
@@ -93,9 +105,6 @@ class AIHub:
93
105
  "name": template.name,
94
106
  "description": template.description,
95
107
  "creator_username": template.creator_username,
96
- "created_on": template.creation_timestamp.strftime("%Y-%m-%d %H:%M:%S")
97
- if template.creation_timestamp
98
- else None,
99
108
  }
100
109
  results.append(result)
101
110
  return results
@@ -134,11 +143,11 @@ class AIHub:
134
143
  Example:
135
144
  from lightning_sdk import AIHub
136
145
  hub = AIHub()
137
- deployment = hub.deploy("temp_01jc37n6qpqkdptjpyep0z06hy")
146
+ deployment = hub.deploy("temp_xxxx")
138
147
 
139
148
  # Using API arguments
140
- api_arugments = {"batch_size" 10, "batch_timeout": 0.001, "env_token": "lit_xxxx"}
141
- deployment = hub.deploy("temp_01jc37n6qpqkdptjpyep0z06hy", api_arugments=api_arugments)
149
+ api_arugments = {"model": "unitary/toxic-bert", "batch_size" 10, "token": "lit_xxxx"}
150
+ deployment = hub.deploy("temp_xxxx", api_arugments=api_arugments)
142
151
 
143
152
  Args:
144
153
  api_id: The ID of the API you want to deploy.
@@ -5,6 +5,7 @@ from lightning_sdk.api.studio_api import _cloud_url
5
5
  from lightning_sdk.cli.ai_hub import _AIHub
6
6
  from lightning_sdk.cli.download import _Downloads
7
7
  from lightning_sdk.cli.legacy import _LegacyLightningCLI
8
+ from lightning_sdk.cli.run import _Run
8
9
  from lightning_sdk.cli.upload import _Uploads
9
10
  from lightning_sdk.lightning_cloud.login import Auth
10
11
 
@@ -19,8 +20,7 @@ class StudioCLI:
19
20
  self.upload = _Uploads()
20
21
  self.aihub = _AIHub()
21
22
 
22
- if _LIGHTNING_AVAILABLE:
23
- self.run = _LegacyLightningCLI()
23
+ self.run = _Run(legacy_run=_LegacyLightningCLI() if _LIGHTNING_AVAILABLE else None)
24
24
 
25
25
  def login(self) -> None:
26
26
  """Login to Lightning AI Studios."""
@@ -1,8 +1,11 @@
1
- from typing import Tuple
1
+ import os
2
+ from typing import Any, Dict, List, Tuple
2
3
 
3
4
  from lightning_sdk.api import OrgApi, UserApi
4
5
  from lightning_sdk.cli.exceptions import StudioCliError
6
+ from lightning_sdk.lightning_cloud.openapi.models import V1Membership, V1OwnerType
5
7
  from lightning_sdk.teamspace import Teamspace
8
+ from lightning_sdk.user import User
6
9
  from lightning_sdk.utils.resolve import _get_authed_user
7
10
 
8
11
 
@@ -17,22 +20,49 @@ def _parse_model_name(name: str) -> Tuple[str, str, str]:
17
20
  return org_name, teamspace_name, model_name
18
21
 
19
22
 
23
+ def _get_teamspace_and_path(
24
+ ts: V1Membership, org_api: OrgApi, user_api: UserApi, authed_user: User
25
+ ) -> Tuple[str, Dict[str, Any]]:
26
+ if ts.owner_type == V1OwnerType.ORGANIZATION:
27
+ org = org_api._get_org_by_id(ts.owner_id)
28
+ return f"{org.name}/{ts.name}", {"name": ts.name, "org": org.name}
29
+
30
+ if ts.owner_type == V1OwnerType.USER and ts.owner_id != authed_user.id:
31
+ user = user_api._get_user_by_id(ts.owner_id) # todo: check also the name
32
+ return f"{user.username}/{ts.name}", {"name": ts.name, "user": User(name=user.username)}
33
+
34
+ if ts.owner_type == V1OwnerType.USER:
35
+ return f"{authed_user.name}/{ts.name}", {"name": ts.name, "user": authed_user}
36
+
37
+ raise StudioCliError(f"Unknown organization type {ts.owner_type}")
38
+
39
+
40
+ def _list_teamspaces() -> List[str]:
41
+ org_api = OrgApi()
42
+ user_api = UserApi()
43
+ authed_user = _get_authed_user()
44
+
45
+ return [
46
+ _get_teamspace_and_path(ts, org_api, user_api, authed_user)[0]
47
+ for ts in user_api._get_all_teamspace_memberships("")
48
+ ]
49
+
50
+
20
51
  def _get_teamspace(name: str, organization: str) -> Teamspace:
21
52
  """Get a Teamspace object from the SDK."""
22
53
  org_api = OrgApi()
23
- user = _get_authed_user()
24
- teamspaces = {}
25
- for ts in UserApi()._get_all_teamspace_memberships(""):
26
- if ts.owner_type == "organization":
27
- org = org_api._get_org_by_id(ts.owner_id)
28
- teamspaces[f"{org.name}/{ts.name}"] = {"name": ts.name, "org": org.name}
29
- elif ts.owner_type == "user": # todo: check also the name
30
- teamspaces[f"{user.name}/{ts.name}"] = {"name": ts.name, "user": user}
31
- else:
32
- raise StudioCliError(f"Unknown organization type {ts.owner_type}")
54
+ user_api = UserApi()
55
+ authed_user = _get_authed_user()
33
56
 
34
57
  requested_teamspace = f"{organization}/{name}".lower()
35
- if requested_teamspace not in teamspaces:
36
- options = "\n\t".join(teamspaces.keys())
37
- raise StudioCliError(f"Teamspace `{requested_teamspace}` not found. Available teamspaces: \n\t{options}")
38
- return Teamspace(**teamspaces[requested_teamspace])
58
+
59
+ for ts in user_api._get_all_teamspace_memberships(""):
60
+ if ts.name != name:
61
+ continue
62
+
63
+ teamspace_path, teamspace = _get_teamspace_and_path(ts, org_api, user_api, authed_user)
64
+ if requested_teamspace == teamspace_path:
65
+ return Teamspace(**teamspace)
66
+
67
+ options = f"{os.linesep}\t".join(_list_teamspaces())
68
+ raise StudioCliError(f"Teamspace `{requested_teamspace}` not found. Available teamspaces: {os.linesep}\t{options}")
@@ -0,0 +1,72 @@
1
+ from typing import TYPE_CHECKING, Dict, Optional
2
+
3
+ from lightning_sdk.job import Job
4
+ from lightning_sdk.machine import Machine
5
+
6
+ if TYPE_CHECKING:
7
+ from lightning_sdk.cli.legacy import _LegacyLightningCLI
8
+
9
+ _MACHINE_VALUES = tuple([machine.value for machine in Machine])
10
+
11
+
12
+ class _Run:
13
+ """Run async workloads on the Lightning AI platform."""
14
+
15
+ def __init__(self, legacy_run: Optional["_LegacyLightningCLI"] = None) -> None:
16
+ if legacy_run is not None:
17
+ self.app = legacy_run.app
18
+ self.model = legacy_run.model
19
+
20
+ # Need to set the docstring here for f-strings to work.
21
+ # Sadly this is the only way to really show options as f-strings are not allowed as docstrings directly
22
+ # and fire does not show values for literals, just that it is a literal.
23
+ docstr = f"""Run async workloads using a docker image or a compute environment from your studio.
24
+
25
+ Args:
26
+ name: The name of the job. Needs to be unique within the teamspace.
27
+ machine: The machine type to run the job on. One of {", ".join(_MACHINE_VALUES)}.
28
+ command: The command to run inside your job. Required if using a studio. Optional if using an image.
29
+ If not provided for images, will run the container entrypoint and default command.
30
+ studio: The studio env to run the job with. Mutually exclusive with image.
31
+ image: The docker image to run the job with. Mutually exclusive with studio.
32
+ teamspace: The teamspace the job should be associated with. Defaults to the current teamspace.
33
+ org: The organization owning the teamspace (if any). Defaults to the current organization.
34
+ user: The user owning the teamspace (if any). Defaults to the current user.
35
+ cluster: The cluster to run the job on. Defaults to the studio cluster if running with studio compute env.
36
+ If not provided will fall back to the teamspaces default cluster.
37
+ env: Environment variables to set inside the job.
38
+ interruptible: Whether the job should run on interruptible instances. They are cheaper but can be preempted.
39
+ """
40
+ self.job.__func__.__doc__ = docstr
41
+
42
+ # TODO: sadly, fire displays both Optional[type] and Union[type, None] as Optional[Optional]
43
+ # see https://github.com/google/python-fire/pull/513
44
+ # might need to move to different cli library
45
+ def job(
46
+ self,
47
+ name: str,
48
+ machine: str,
49
+ command: Optional[str] = None,
50
+ studio: Optional[str] = None,
51
+ image: Optional[str] = None,
52
+ teamspace: Optional[str] = None,
53
+ org: Optional[str] = None,
54
+ user: Optional[str] = None,
55
+ cluster: Optional[str] = None,
56
+ env: Optional[Dict[str, str]] = None,
57
+ interruptible: bool = False,
58
+ ) -> None:
59
+ machine_enum = Machine(machine.upper())
60
+ Job.run(
61
+ name=name,
62
+ machine=machine_enum,
63
+ command=command,
64
+ studio=studio,
65
+ image=image,
66
+ teamspace=teamspace,
67
+ org=org,
68
+ user=user,
69
+ cluster=cluster,
70
+ env=env,
71
+ interruptible=interruptible,
72
+ )
lightning_sdk/job/base.py CHANGED
@@ -16,15 +16,20 @@ class _BaseJob(ABC):
16
16
  def __init__(
17
17
  self,
18
18
  name: str,
19
- teamspace: Union[str, "Teamspace"] = None,
20
- org: Union[str, "Organization"] = None,
21
- user: Union[str, "User"] = None,
22
- cluster: Optional[str] = None,
19
+ teamspace: Union[str, "Teamspace", None] = None,
20
+ org: Union[str, "Organization", None] = None,
21
+ user: Union[str, "User", None] = None,
23
22
  *,
24
23
  _fetch_job: bool = True,
25
24
  ) -> None:
26
- self._teamspace = _resolve_teamspace(teamspace=teamspace, org=org, user=user)
27
- self._cluster = cluster
25
+ _teamspace = _resolve_teamspace(teamspace=teamspace, org=org, user=user)
26
+ if _teamspace is None:
27
+ raise ValueError(
28
+ "Cannot resolve the teamspace from provided arguments."
29
+ f" Got teamspace={teamspace}, org={org}, user={user}."
30
+ )
31
+ else:
32
+ self._teamspace = _teamspace
28
33
  self._name = name
29
34
  self._job = None
30
35
 
@@ -37,18 +42,25 @@ class _BaseJob(ABC):
37
42
  name: str,
38
43
  machine: "Machine",
39
44
  command: Optional[str] = None,
40
- studio: Optional["Studio"] = None,
45
+ studio: Union["Studio", str, None] = None,
41
46
  image: Optional[str] = None,
42
- teamspace: Union[str, "Teamspace"] = None,
43
- org: Union[str, "Organization"] = None,
44
- user: Union[str, "User"] = None,
47
+ teamspace: Union[str, "Teamspace", None] = None,
48
+ org: Union[str, "Organization", None] = None,
49
+ user: Union[str, "User", None] = None,
45
50
  cluster: Optional[str] = None,
46
51
  env: Optional[Dict[str, str]] = None,
47
52
  interruptible: bool = False,
48
53
  ) -> "_BaseJob":
54
+ from lightning_sdk.studio import Studio
55
+
49
56
  if not name:
50
57
  raise ValueError("A job needs to have a name!")
51
- if studio is not None:
58
+
59
+ if image is None:
60
+ if not isinstance(studio, Studio):
61
+ studio = Studio(name=studio, teamspace=teamspace, org=org, user=user, cluster=cluster, create_ok=False)
62
+
63
+ # studio is a Studio instance at this point
52
64
  if teamspace is None:
53
65
  teamspace = studio.teamspace
54
66
  else:
@@ -60,11 +72,30 @@ class _BaseJob(ABC):
60
72
  "Can only run jobs with Studio envs in the teamspace of that Studio."
61
73
  )
62
74
 
63
- # TODO: resolve studio and support string studios
64
- # TODO: assertions for studio to be on cluster
65
- # TODO: if cluster is not provided use studio cluster if provided, otherwise use default cluster from teamspace
66
- inst = cls(name=name, teamspace=teamspace, org=org, user=user, cluster=cluster, _fetch_job=False)
67
- inst._submit(machine=machine, command=command, studio=studio, image=image, env=env, interruptible=interruptible)
75
+ if cluster is None:
76
+ cluster = studio.cluster
77
+
78
+ if cluster != studio.cluster:
79
+ raise ValueError(
80
+ "Studio cluster does not match provided cluster. "
81
+ "Can only run jobs with Studio envs in the same cluster."
82
+ )
83
+ else:
84
+ if studio is not None:
85
+ raise RuntimeError(
86
+ "image and studio are mutually exclusive as both define the environment to run the job in"
87
+ )
88
+
89
+ inst = cls(name=name, teamspace=teamspace, org=org, user=user, _fetch_job=False)
90
+ inst._submit(
91
+ machine=machine,
92
+ cluster=cluster,
93
+ command=command,
94
+ studio=studio,
95
+ image=image,
96
+ env=env,
97
+ interruptible=interruptible,
98
+ )
68
99
  return inst
69
100
 
70
101
  @abstractmethod
@@ -76,6 +107,7 @@ class _BaseJob(ABC):
76
107
  image: Optional[str] = None,
77
108
  env: Optional[Dict[str, str]] = None,
78
109
  interruptible: bool = False,
110
+ cluster: Optional[str] = None,
79
111
  ) -> None:
80
112
  """Submits a job and updates the internal _job attribute as well as the _name attribute."""
81
113
 
@@ -123,7 +155,3 @@ class _BaseJob(ABC):
123
155
  @property
124
156
  def teamspace(self) -> "Teamspace":
125
157
  return self._teamspace
126
-
127
- @property
128
- def cluster(self) -> Optional[str]:
129
- return self._cluster
lightning_sdk/job/job.py CHANGED
@@ -28,17 +28,20 @@ class Job(_BaseJob):
28
28
  def __init__(
29
29
  self,
30
30
  name: str,
31
- teamspace: Union[str, "Teamspace"] = None,
32
- org: Union[str, "Organization"] = None,
33
- user: Union[str, "User"] = None,
34
- cluster: Optional[str] = None,
31
+ teamspace: Union[str, "Teamspace", None] = None,
32
+ org: Union[str, "Organization", None] = None,
33
+ user: Union[str, "User", None] = None,
35
34
  *,
36
35
  _fetch_job: bool = True,
37
36
  ) -> None:
38
37
  internal_job_cls = _JobV2 if _has_jobs_v2() else _JobV1
39
38
 
40
39
  self._internal_job = internal_job_cls(
41
- name=name, teamspace=teamspace, org=org, user=user, cluster=cluster, _fetch_job=_fetch_job
40
+ name=name,
41
+ teamspace=teamspace,
42
+ org=org,
43
+ user=user,
44
+ _fetch_job=_fetch_job,
42
45
  )
43
46
 
44
47
  @classmethod
@@ -47,11 +50,11 @@ class Job(_BaseJob):
47
50
  name: str,
48
51
  machine: "Machine",
49
52
  command: Optional[str] = None,
50
- studio: Optional["Studio"] = None,
51
- image: Optional[str] = None,
52
- teamspace: Union[str, "Teamspace"] = None,
53
- org: Union[str, "Organization"] = None,
54
- user: Union[str, "User"] = None,
53
+ studio: Union["Studio", str, None] = None,
54
+ image: Union[str, None] = None,
55
+ teamspace: Union[str, "Teamspace", None] = None,
56
+ org: Union[str, "Organization", None] = None,
57
+ user: Union[str, "User", None] = None,
55
58
  cluster: Optional[str] = None,
56
59
  env: Optional[Dict[str, str]] = None,
57
60
  interruptible: bool = False,
@@ -81,9 +84,16 @@ class Job(_BaseJob):
81
84
  image: Optional[str] = None,
82
85
  env: Optional[Dict[str, str]] = None,
83
86
  interruptible: bool = False,
87
+ cluster: Optional[str] = None,
84
88
  ) -> None:
85
89
  return self._internal_job._submit(
86
- machine=machine, command=command, studio=studio, image=image, env=env, interruptible=interruptible
90
+ machine=machine,
91
+ cluster=cluster,
92
+ command=command,
93
+ studio=studio,
94
+ image=image,
95
+ env=env,
96
+ interruptible=interruptible,
87
97
  )
88
98
 
89
99
  def stop(self) -> None:
lightning_sdk/job/v1.py CHANGED
@@ -20,15 +20,14 @@ class _JobV1(_BaseJob):
20
20
  def __init__(
21
21
  self,
22
22
  name: str,
23
- teamspace: Union[str, "Teamspace"] = None,
24
- org: Union[str, "Organization"] = None,
25
- user: Union[str, "User"] = None,
26
- cluster: Optional[str] = None,
23
+ teamspace: Union[str, "Teamspace", None] = None,
24
+ org: Union[str, "Organization", None] = None,
25
+ user: Union[str, "User", None] = None,
27
26
  *,
28
27
  _fetch_job: bool = True,
29
28
  ) -> None:
30
29
  self._job_api = JobApiV1()
31
- super().__init__(name=name, teamspace=teamspace, org=org, user=user, cluster=cluster, _fetch_job=_fetch_job)
30
+ super().__init__(name=name, teamspace=teamspace, org=org, user=user, _fetch_job=_fetch_job)
32
31
 
33
32
  @classmethod
34
33
  def run(
@@ -37,9 +36,9 @@ class _JobV1(_BaseJob):
37
36
  machine: "Machine",
38
37
  command: str,
39
38
  studio: "Studio",
40
- teamspace: Union[str, "Teamspace"] = None,
41
- org: Union[str, "Organization"] = None,
42
- user: Union[str, "User"] = None,
39
+ teamspace: Union[str, "Teamspace", None] = None,
40
+ org: Union[str, "Organization", None] = None,
41
+ user: Union[str, "User", None] = None,
43
42
  cluster: Optional[str] = None,
44
43
  interruptible: bool = False,
45
44
  ) -> "_BaseJob":
@@ -65,6 +64,7 @@ class _JobV1(_BaseJob):
65
64
  image: Optional[str] = None,
66
65
  env: Optional[Dict[str, str]] = None,
67
66
  interruptible: bool = False,
67
+ cluster: Optional[str] = None,
68
68
  ) -> None:
69
69
  if studio is None:
70
70
  raise ValueError("Studio is required for submitting jobs")
@@ -85,7 +85,7 @@ class _JobV1(_BaseJob):
85
85
  command=command,
86
86
  studio_id=studio._studio.id,
87
87
  teamspace_id=self._teamspace.id,
88
- cluster_id=self._cluster,
88
+ cluster_id=cluster,
89
89
  machine=machine,
90
90
  interruptible=interruptible,
91
91
  )
lightning_sdk/job/v2.py CHANGED
@@ -16,15 +16,14 @@ class _JobV2(_BaseJob):
16
16
  def __init__(
17
17
  self,
18
18
  name: str,
19
- teamspace: Union[str, "Teamspace"] = None,
20
- org: Union[str, "Organization"] = None,
21
- user: Union[str, "User"] = None,
22
- cluster: Optional[str] = None,
19
+ teamspace: Union[str, "Teamspace", None] = None,
20
+ org: Union[str, "Organization", None] = None,
21
+ user: Union[str, "User", None] = None,
23
22
  *,
24
23
  _fetch_job: bool = True,
25
24
  ) -> None:
26
25
  self._job_api = JobApiV2()
27
- super().__init__(name=name, teamspace=teamspace, org=org, user=user, cluster=cluster, _fetch_job=_fetch_job)
26
+ super().__init__(name=name, teamspace=teamspace, org=org, user=user, _fetch_job=_fetch_job)
28
27
 
29
28
  def _submit(
30
29
  self,
@@ -34,6 +33,7 @@ class _JobV2(_BaseJob):
34
33
  image: Optional[str] = None,
35
34
  env: Optional[Dict[str, str]] = None,
36
35
  interruptible: bool = False,
36
+ cluster: Optional[str] = None,
37
37
  ) -> None:
38
38
  # Command is required if Studio is provided to know what to run
39
39
  # Image is mutually exclusive with Studio
@@ -55,7 +55,7 @@ class _JobV2(_BaseJob):
55
55
  submitted = self._job_api.submit_job(
56
56
  name=self.name,
57
57
  command=command,
58
- cluster_id=self._cluster,
58
+ cluster_id=cluster,
59
59
  teamspace_id=self._teamspace.id,
60
60
  studio_id=studio_id,
61
61
  image=image,
@@ -47,6 +47,7 @@ class CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs(o
47
47
  'endpoint': 'V1Endpoint',
48
48
  'name': 'str',
49
49
  'parameter_spec': 'V1ParameterizationSpec',
50
+ 'parent_template_id': 'str',
50
51
  'replicas': 'int',
51
52
  'spec': 'V1JobSpec',
52
53
  'strategy': 'V1DeploymentStrategy'
@@ -59,12 +60,13 @@ class CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs(o
59
60
  'endpoint': 'endpoint',
60
61
  'name': 'name',
61
62
  'parameter_spec': 'parameterSpec',
63
+ 'parent_template_id': 'parentTemplateId',
62
64
  'replicas': 'replicas',
63
65
  'spec': 'spec',
64
66
  'strategy': 'strategy'
65
67
  }
66
68
 
67
- def __init__(self, autoscaling: 'V1AutoscalingSpec' =None, cloudspace_id: 'str' =None, cluster_id: 'str' =None, endpoint: 'V1Endpoint' =None, name: 'str' =None, parameter_spec: 'V1ParameterizationSpec' =None, replicas: 'int' =None, spec: 'V1JobSpec' =None, strategy: 'V1DeploymentStrategy' =None): # noqa: E501
69
+ def __init__(self, autoscaling: 'V1AutoscalingSpec' =None, cloudspace_id: 'str' =None, cluster_id: 'str' =None, endpoint: 'V1Endpoint' =None, name: 'str' =None, parameter_spec: 'V1ParameterizationSpec' =None, parent_template_id: 'str' =None, replicas: 'int' =None, spec: 'V1JobSpec' =None, strategy: 'V1DeploymentStrategy' =None): # noqa: E501
68
70
  """CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs - a model defined in Swagger""" # noqa: E501
69
71
  self._autoscaling = None
70
72
  self._cloudspace_id = None
@@ -72,6 +74,7 @@ class CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs(o
72
74
  self._endpoint = None
73
75
  self._name = None
74
76
  self._parameter_spec = None
77
+ self._parent_template_id = None
75
78
  self._replicas = None
76
79
  self._spec = None
77
80
  self._strategy = None
@@ -88,6 +91,8 @@ class CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs(o
88
91
  self.name = name
89
92
  if parameter_spec is not None:
90
93
  self.parameter_spec = parameter_spec
94
+ if parent_template_id is not None:
95
+ self.parent_template_id = parent_template_id
91
96
  if replicas is not None:
92
97
  self.replicas = replicas
93
98
  if spec is not None:
@@ -221,6 +226,27 @@ class CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs(o
221
226
 
222
227
  self._parameter_spec = parameter_spec
223
228
 
229
+ @property
230
+ def parent_template_id(self) -> 'str':
231
+ """Gets the parent_template_id of this CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs. # noqa: E501
232
+
233
+
234
+ :return: The parent_template_id of this CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs. # noqa: E501
235
+ :rtype: str
236
+ """
237
+ return self._parent_template_id
238
+
239
+ @parent_template_id.setter
240
+ def parent_template_id(self, parent_template_id: 'str'):
241
+ """Sets the parent_template_id of this CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs.
242
+
243
+
244
+ :param parent_template_id: The parent_template_id of this CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs. # noqa: E501
245
+ :type: str
246
+ """
247
+
248
+ self._parent_template_id = parent_template_id
249
+
224
250
  @property
225
251
  def replicas(self) -> 'int':
226
252
  """Gets the replicas of this CreateDeploymentRequestDefinesASpecForTheJobThatAllowsForAutoscalingJobs. # noqa: E501
@@ -54,6 +54,7 @@ class DeploymentsIdBody(object):
54
54
  'spec': 'V1JobSpec',
55
55
  'status': 'V1DeploymentStatus',
56
56
  'strategy': 'V1DeploymentStrategy',
57
+ 'template_id': 'str',
57
58
  'updated_at': 'datetime',
58
59
  'user_id': 'str'
59
60
  }
@@ -72,11 +73,12 @@ class DeploymentsIdBody(object):
72
73
  'spec': 'spec',
73
74
  'status': 'status',
74
75
  'strategy': 'strategy',
76
+ 'template_id': 'templateId',
75
77
  'updated_at': 'updatedAt',
76
78
  'user_id': 'userId'
77
79
  }
78
80
 
79
- def __init__(self, autoscaling: 'V1AutoscalingSpec' =None, cloudspace_id: 'str' =None, created_at: 'datetime' =None, desired_state: 'V1DeploymentState' =None, endpoint: 'V1Endpoint' =None, is_published: 'bool' =None, name: 'str' =None, parameter_spec: 'V1ParameterizationSpec' =None, release_id: 'str' =None, replicas: 'int' =None, spec: 'V1JobSpec' =None, status: 'V1DeploymentStatus' =None, strategy: 'V1DeploymentStrategy' =None, updated_at: 'datetime' =None, user_id: 'str' =None): # noqa: E501
81
+ def __init__(self, autoscaling: 'V1AutoscalingSpec' =None, cloudspace_id: 'str' =None, created_at: 'datetime' =None, desired_state: 'V1DeploymentState' =None, endpoint: 'V1Endpoint' =None, is_published: 'bool' =None, name: 'str' =None, parameter_spec: 'V1ParameterizationSpec' =None, release_id: 'str' =None, replicas: 'int' =None, spec: 'V1JobSpec' =None, status: 'V1DeploymentStatus' =None, strategy: 'V1DeploymentStrategy' =None, template_id: 'str' =None, updated_at: 'datetime' =None, user_id: 'str' =None): # noqa: E501
80
82
  """DeploymentsIdBody - a model defined in Swagger""" # noqa: E501
81
83
  self._autoscaling = None
82
84
  self._cloudspace_id = None
@@ -91,6 +93,7 @@ class DeploymentsIdBody(object):
91
93
  self._spec = None
92
94
  self._status = None
93
95
  self._strategy = None
96
+ self._template_id = None
94
97
  self._updated_at = None
95
98
  self._user_id = None
96
99
  self.discriminator = None
@@ -120,6 +123,8 @@ class DeploymentsIdBody(object):
120
123
  self.status = status
121
124
  if strategy is not None:
122
125
  self.strategy = strategy
126
+ if template_id is not None:
127
+ self.template_id = template_id
123
128
  if updated_at is not None:
124
129
  self.updated_at = updated_at
125
130
  if user_id is not None:
@@ -398,6 +403,27 @@ class DeploymentsIdBody(object):
398
403
 
399
404
  self._strategy = strategy
400
405
 
406
+ @property
407
+ def template_id(self) -> 'str':
408
+ """Gets the template_id of this DeploymentsIdBody. # noqa: E501
409
+
410
+
411
+ :return: The template_id of this DeploymentsIdBody. # noqa: E501
412
+ :rtype: str
413
+ """
414
+ return self._template_id
415
+
416
+ @template_id.setter
417
+ def template_id(self, template_id: 'str'):
418
+ """Sets the template_id of this DeploymentsIdBody.
419
+
420
+
421
+ :param template_id: The template_id of this DeploymentsIdBody. # noqa: E501
422
+ :type: str
423
+ """
424
+
425
+ self._template_id = template_id
426
+
401
427
  @property
402
428
  def updated_at(self) -> 'datetime':
403
429
  """Gets the updated_at of this DeploymentsIdBody. # noqa: E501