polyaxon 2.1.8__py3-none-any.whl → 2.2.0.post1__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.
- polyaxon/_cli/artifacts.py +16 -12
- polyaxon/_cli/components.py +16 -12
- polyaxon/_cli/config.py +31 -0
- polyaxon/_cli/dashboard.py +15 -2
- polyaxon/_cli/init.py +1 -1
- polyaxon/_cli/models.py +16 -12
- polyaxon/_cli/operations.py +100 -54
- polyaxon/_cli/project_versions.py +26 -5
- polyaxon/_cli/projects.py +23 -9
- polyaxon/_cli/run.py +29 -9
- polyaxon/_client/mixin.py +39 -0
- polyaxon/_client/project.py +22 -22
- polyaxon/_client/run.py +44 -25
- polyaxon/_compiler/contexts/ray_job.py +4 -2
- polyaxon/_deploy/schemas/proxy.py +1 -0
- polyaxon/_env_vars/getters/owner_entity.py +4 -2
- polyaxon/_env_vars/getters/project.py +4 -2
- polyaxon/_env_vars/getters/run.py +2 -2
- polyaxon/_env_vars/keys.py +1 -0
- polyaxon/_k8s/converter/base/main.py +1 -0
- polyaxon/_k8s/converter/common/accelerators.py +7 -4
- polyaxon/_k8s/converter/converters/ray_job.py +4 -2
- polyaxon/_k8s/custom_resources/setter.py +1 -1
- polyaxon/_local_process/__init__.py +0 -0
- polyaxon/_local_process/agent.py +6 -0
- polyaxon/_local_process/converter/__init__.py +1 -0
- polyaxon/_local_process/converter/base/__init__.py +1 -0
- polyaxon/_local_process/converter/base/base.py +140 -0
- polyaxon/_local_process/converter/base/containers.py +69 -0
- polyaxon/_local_process/converter/base/env_vars.py +253 -0
- polyaxon/_local_process/converter/base/init.py +414 -0
- polyaxon/_local_process/converter/base/main.py +74 -0
- polyaxon/_local_process/converter/base/mounts.py +82 -0
- polyaxon/_local_process/converter/converters/__init__.py +8 -0
- polyaxon/_local_process/converter/converters/job.py +40 -0
- polyaxon/_local_process/converter/converters/service.py +41 -0
- polyaxon/_local_process/converter/mixins.py +38 -0
- polyaxon/_local_process/executor.py +132 -0
- polyaxon/_local_process/process_types.py +39 -0
- polyaxon/_sdk/api/organizations_v1_api.py +8 -8
- polyaxon/_sdk/api/project_dashboards_v1_api.py +12 -12
- polyaxon/_sdk/api/project_searches_v1_api.py +12 -12
- polyaxon/_sdk/api/projects_v1_api.py +221 -44
- polyaxon/_sdk/api/runs_v1_api.py +156 -202
- polyaxon/_sdk/api/service_accounts_v1_api.py +4 -4
- polyaxon/_sdk/api/teams_v1_api.py +2827 -375
- polyaxon/_sdk/api/users_v1_api.py +231 -55
- polyaxon/_sdk/schemas/v1_settings_catalog.py +1 -0
- polyaxon/_sdk/schemas/v1_team.py +3 -0
- polyaxon/_sdk/schemas/v1_user.py +1 -2
- polyaxon/_utils/fqn_utils.py +25 -2
- polyaxon/pkg.py +1 -1
- {polyaxon-2.1.8.dist-info → polyaxon-2.2.0.post1.dist-info}/METADATA +8 -8
- {polyaxon-2.1.8.dist-info → polyaxon-2.2.0.post1.dist-info}/RECORD +58 -41
- {polyaxon-2.1.8.dist-info → polyaxon-2.2.0.post1.dist-info}/LICENSE +0 -0
- {polyaxon-2.1.8.dist-info → polyaxon-2.2.0.post1.dist-info}/WHEEL +0 -0
- {polyaxon-2.1.8.dist-info → polyaxon-2.2.0.post1.dist-info}/entry_points.txt +0 -0
- {polyaxon-2.1.8.dist-info → polyaxon-2.2.0.post1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
from polyaxon import settings
|
2
|
+
from polyaxon._client.client import PolyaxonClient
|
3
|
+
from polyaxon._schemas.client import ClientConfig
|
4
|
+
from polyaxon._utils.fqn_utils import split_owner_team_space
|
5
|
+
|
6
|
+
|
7
|
+
class ClientMixin:
|
8
|
+
@property
|
9
|
+
def client(self):
|
10
|
+
if self._client:
|
11
|
+
return self._client
|
12
|
+
self._client = PolyaxonClient()
|
13
|
+
return self._client
|
14
|
+
|
15
|
+
def reset_client(self, **kwargs):
|
16
|
+
if not settings.CLIENT_CONFIG.in_cluster:
|
17
|
+
self._client = PolyaxonClient(
|
18
|
+
ClientConfig.patch_from(settings.CLIENT_CONFIG, **kwargs)
|
19
|
+
)
|
20
|
+
|
21
|
+
@property
|
22
|
+
def owner(self) -> str:
|
23
|
+
return self._owner
|
24
|
+
|
25
|
+
@property
|
26
|
+
def team(self):
|
27
|
+
return self._team
|
28
|
+
|
29
|
+
@property
|
30
|
+
def project(self) -> str:
|
31
|
+
return self._project
|
32
|
+
|
33
|
+
def set_project(self, project: str):
|
34
|
+
self._project = project
|
35
|
+
|
36
|
+
def set_owner(self, owner: str):
|
37
|
+
owner, team = split_owner_team_space(owner)
|
38
|
+
self._owner = owner
|
39
|
+
self._team = team
|
polyaxon/_client/project.py
CHANGED
@@ -12,6 +12,7 @@ from clipped.utils.validation import validate_tags
|
|
12
12
|
|
13
13
|
from polyaxon._client.client import PolyaxonClient
|
14
14
|
from polyaxon._client.decorators import client_handler, get_global_or_inline_config
|
15
|
+
from polyaxon._client.mixin import ClientMixin
|
15
16
|
from polyaxon._constants.globals import DEFAULT
|
16
17
|
from polyaxon._contexts import paths as ctx_paths
|
17
18
|
from polyaxon._env_vars.getters.user import get_local_owner
|
@@ -21,13 +22,17 @@ from polyaxon._sdk.schemas.v1_list_project_versions_response import (
|
|
21
22
|
)
|
22
23
|
from polyaxon._sdk.schemas.v1_project import V1Project
|
23
24
|
from polyaxon._sdk.schemas.v1_project_version import V1ProjectVersion
|
24
|
-
from polyaxon._utils.fqn_utils import
|
25
|
+
from polyaxon._utils.fqn_utils import (
|
26
|
+
get_entity_full_name,
|
27
|
+
get_entity_info,
|
28
|
+
split_owner_team_space,
|
29
|
+
)
|
25
30
|
from polyaxon.exceptions import ApiException, PolyaxonClientException
|
26
31
|
from polyaxon.logger import logger
|
27
32
|
from traceml.artifacts import V1RunArtifact
|
28
33
|
|
29
34
|
|
30
|
-
class ProjectClient:
|
35
|
+
class ProjectClient(ClientMixin):
|
31
36
|
"""ProjectClient is a client to communicate with Polyaxon projects endpoints.
|
32
37
|
|
33
38
|
If no values are passed to this class,
|
@@ -94,26 +99,13 @@ class ProjectClient:
|
|
94
99
|
if not owner:
|
95
100
|
raise PolyaxonClientException("Please provide a valid owner.")
|
96
101
|
|
102
|
+
owner, team = split_owner_team_space(owner)
|
97
103
|
self._client = client
|
98
104
|
self._owner = owner or DEFAULT
|
105
|
+
self._team = team
|
99
106
|
self._project = project
|
100
107
|
self._project_data = V1Project.construct()
|
101
108
|
|
102
|
-
@property
|
103
|
-
def client(self):
|
104
|
-
if self._client:
|
105
|
-
return self._client
|
106
|
-
self._client = PolyaxonClient()
|
107
|
-
return self._client
|
108
|
-
|
109
|
-
@property
|
110
|
-
def owner(self):
|
111
|
-
return self._owner
|
112
|
-
|
113
|
-
@property
|
114
|
-
def project(self):
|
115
|
-
return self._project
|
116
|
-
|
117
109
|
@property
|
118
110
|
def project_data(self):
|
119
111
|
return self._project_data
|
@@ -139,11 +131,19 @@ class ProjectClient:
|
|
139
131
|
Returns:
|
140
132
|
V1Project, project instance from the response.
|
141
133
|
"""
|
142
|
-
|
143
|
-
self.
|
144
|
-
|
145
|
-
|
146
|
-
|
134
|
+
if self.team:
|
135
|
+
self._project_data = self.client.projects_v1.create_team_project(
|
136
|
+
self.owner,
|
137
|
+
self.team,
|
138
|
+
data,
|
139
|
+
async_req=False,
|
140
|
+
)
|
141
|
+
else:
|
142
|
+
self._project_data = self.client.projects_v1.create_project(
|
143
|
+
self.owner,
|
144
|
+
data,
|
145
|
+
async_req=False,
|
146
|
+
)
|
147
147
|
self._project_data.owner = self.owner
|
148
148
|
self._project = self._project_data.name
|
149
149
|
return self._project_data
|
polyaxon/_client/run.py
CHANGED
@@ -35,6 +35,7 @@ from polyaxon import settings
|
|
35
35
|
from polyaxon._cli.errors import handle_cli_error
|
36
36
|
from polyaxon._client.client import PolyaxonClient
|
37
37
|
from polyaxon._client.decorators import client_handler, get_global_or_inline_config
|
38
|
+
from polyaxon._client.mixin import ClientMixin
|
38
39
|
from polyaxon._client.store import PolyaxonStore
|
39
40
|
from polyaxon._constants.metadata import META_COPY_ARTIFACTS, META_RECOMPILE
|
40
41
|
from polyaxon._containers.names import MAIN_CONTAINER_NAMES
|
@@ -63,7 +64,11 @@ from polyaxon._sdk.schemas.v1_operation_body import V1OperationBody
|
|
63
64
|
from polyaxon._sdk.schemas.v1_project_version import V1ProjectVersion
|
64
65
|
from polyaxon._sdk.schemas.v1_run import V1Run
|
65
66
|
from polyaxon._sdk.schemas.v1_run_settings import V1RunSettings
|
66
|
-
from polyaxon._utils.fqn_utils import
|
67
|
+
from polyaxon._utils.fqn_utils import (
|
68
|
+
get_entity_full_name,
|
69
|
+
split_owner_team_space,
|
70
|
+
to_fqn_name,
|
71
|
+
)
|
67
72
|
from polyaxon._utils.urls_utils import get_proxy_run_url
|
68
73
|
from polyaxon.api import K8S_V1_LOCATION, STREAMS_V1_LOCATION
|
69
74
|
from polyaxon.exceptions import ApiException, PolyaxonClientException
|
@@ -80,7 +85,7 @@ if TYPE_CHECKING:
|
|
80
85
|
from traceml.tracking.run import Run
|
81
86
|
|
82
87
|
|
83
|
-
class RunClient:
|
88
|
+
class RunClient(ClientMixin):
|
84
89
|
"""RunClient is a client to communicate with Polyaxon runs endpoints.
|
85
90
|
|
86
91
|
If no values are passed to this class,
|
@@ -146,7 +151,7 @@ class RunClient:
|
|
146
151
|
return
|
147
152
|
|
148
153
|
try:
|
149
|
-
owner, project = get_project_or_local(
|
154
|
+
owner, _, project = get_project_or_local(
|
150
155
|
get_entity_full_name(owner=owner, entity=project)
|
151
156
|
)
|
152
157
|
except PolyaxonClientException:
|
@@ -166,8 +171,10 @@ class RunClient:
|
|
166
171
|
if error_message and not self._is_offline:
|
167
172
|
raise PolyaxonClientException(error_message)
|
168
173
|
|
174
|
+
owner, team = split_owner_team_space(owner)
|
169
175
|
self._client = client
|
170
176
|
self._owner = owner
|
177
|
+
self._team = team
|
171
178
|
self._project = project
|
172
179
|
self._run_uuid = (
|
173
180
|
get_run_or_local(run_uuid)
|
@@ -218,12 +225,11 @@ class RunClient:
|
|
218
225
|
return client.config.no_op
|
219
226
|
return settings.CLIENT_CONFIG.no_op
|
220
227
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
return self._client
|
228
|
+
def _use_agent_host(self):
|
229
|
+
if self.settings.agent and self.settings.agent.url:
|
230
|
+
self.reset_client(
|
231
|
+
host=self.settings.agent.url, POLYAXON_HOST=self.settings.agent.url
|
232
|
+
)
|
227
233
|
|
228
234
|
@property
|
229
235
|
def store(self):
|
@@ -256,20 +262,6 @@ class RunClient:
|
|
256
262
|
return self.settings.artifacts_store.name
|
257
263
|
return None
|
258
264
|
|
259
|
-
@property
|
260
|
-
def owner(self) -> str:
|
261
|
-
return self._owner or ""
|
262
|
-
|
263
|
-
def set_owner(self, owner: str):
|
264
|
-
self._owner = owner
|
265
|
-
|
266
|
-
@property
|
267
|
-
def project(self) -> str:
|
268
|
-
return self._project or ""
|
269
|
-
|
270
|
-
def set_project(self, project: str):
|
271
|
-
self._project = project
|
272
|
-
|
273
265
|
@property
|
274
266
|
def run_uuid(self) -> str:
|
275
267
|
return self._run_uuid
|
@@ -898,6 +890,7 @@ class RunClient:
|
|
898
890
|
"""
|
899
891
|
if not self.settings:
|
900
892
|
self.refresh_data()
|
893
|
+
self._use_agent_host()
|
901
894
|
params = get_logs_params(
|
902
895
|
last_file=last_file, last_time=last_time, connection=self.artifacts_store
|
903
896
|
)
|
@@ -921,6 +914,7 @@ class RunClient:
|
|
921
914
|
def inspect(self):
|
922
915
|
if not self.settings:
|
923
916
|
self.refresh_data()
|
917
|
+
self._use_agent_host()
|
924
918
|
params = get_streams_params(connection=self.artifacts_store, status=self.status)
|
925
919
|
return self.client.runs_v1.inspect_run(
|
926
920
|
self.namespace, self.owner, self.project, self.run_uuid, **params
|
@@ -994,6 +988,10 @@ class RunClient:
|
|
994
988
|
if not container:
|
995
989
|
container = pod_containers[0]
|
996
990
|
|
991
|
+
if not self.settings:
|
992
|
+
self.refresh_data()
|
993
|
+
self._use_agent_host()
|
994
|
+
|
997
995
|
url = get_proxy_run_url(
|
998
996
|
service=K8S_V1_LOCATION,
|
999
997
|
namespace=self.namespace,
|
@@ -1039,6 +1037,8 @@ class RunClient:
|
|
1039
1037
|
"""
|
1040
1038
|
if not self.settings:
|
1041
1039
|
self.refresh_data()
|
1040
|
+
self._use_agent_host()
|
1041
|
+
|
1042
1042
|
params = get_streams_params(self.artifacts_store)
|
1043
1043
|
return self.client.runs_v1.get_run_events(
|
1044
1044
|
self.namespace,
|
@@ -1074,6 +1074,8 @@ class RunClient:
|
|
1074
1074
|
"""
|
1075
1075
|
if not self.settings:
|
1076
1076
|
self.refresh_data()
|
1077
|
+
self._use_agent_host()
|
1078
|
+
|
1077
1079
|
params = get_streams_params(self.artifacts_store)
|
1078
1080
|
return self.client.runs_v1.get_multi_run_events(
|
1079
1081
|
self.namespace,
|
@@ -1310,6 +1312,7 @@ class RunClient:
|
|
1310
1312
|
"""
|
1311
1313
|
if not self.settings:
|
1312
1314
|
self.refresh_data()
|
1315
|
+
self._use_agent_host()
|
1313
1316
|
params = get_streams_params(self.artifacts_store)
|
1314
1317
|
return self.client.runs_v1.get_run_artifact(
|
1315
1318
|
namespace=self.namespace,
|
@@ -1343,6 +1346,10 @@ class RunClient:
|
|
1343
1346
|
if not self.run_uuid:
|
1344
1347
|
return
|
1345
1348
|
|
1349
|
+
if not self.settings:
|
1350
|
+
self.refresh_data()
|
1351
|
+
self._use_agent_host()
|
1352
|
+
|
1346
1353
|
lineage_path = lineage.path or ""
|
1347
1354
|
summary = lineage.summary or {}
|
1348
1355
|
is_event = summary.get("is_event")
|
@@ -1421,6 +1428,8 @@ class RunClient:
|
|
1421
1428
|
"""
|
1422
1429
|
if not self.settings:
|
1423
1430
|
self.refresh_data()
|
1431
|
+
self._use_agent_host()
|
1432
|
+
|
1424
1433
|
url = get_proxy_run_url(
|
1425
1434
|
service=STREAMS_V1_LOCATION,
|
1426
1435
|
namespace=self.namespace,
|
@@ -1460,6 +1469,8 @@ class RunClient:
|
|
1460
1469
|
"""
|
1461
1470
|
if not self.settings:
|
1462
1471
|
self.refresh_data()
|
1472
|
+
self._use_agent_host()
|
1473
|
+
|
1463
1474
|
url = get_proxy_run_url(
|
1464
1475
|
service=STREAMS_V1_LOCATION,
|
1465
1476
|
namespace=self.namespace,
|
@@ -1507,6 +1518,7 @@ class RunClient:
|
|
1507
1518
|
"""
|
1508
1519
|
if not self.settings:
|
1509
1520
|
self.refresh_data()
|
1521
|
+
self._use_agent_host()
|
1510
1522
|
|
1511
1523
|
params = get_streams_params(connection=self.artifacts_store)
|
1512
1524
|
url = get_proxy_run_url(
|
@@ -1596,6 +1608,7 @@ class RunClient:
|
|
1596
1608
|
|
1597
1609
|
if not self.settings:
|
1598
1610
|
self.refresh_data()
|
1611
|
+
self._use_agent_host()
|
1599
1612
|
|
1600
1613
|
params = get_streams_params(connection=self.artifacts_store)
|
1601
1614
|
url = get_proxy_run_url(
|
@@ -1626,6 +1639,8 @@ class RunClient:
|
|
1626
1639
|
"""
|
1627
1640
|
if not self.settings:
|
1628
1641
|
self.refresh_data()
|
1642
|
+
self._use_agent_host()
|
1643
|
+
|
1629
1644
|
params = get_streams_params(connection=self.artifacts_store)
|
1630
1645
|
self.client.runs_v1.delete_run_artifact(
|
1631
1646
|
namespace=self.namespace,
|
@@ -1645,6 +1660,8 @@ class RunClient:
|
|
1645
1660
|
"""
|
1646
1661
|
if not self.settings:
|
1647
1662
|
self.refresh_data()
|
1663
|
+
self._use_agent_host()
|
1664
|
+
|
1648
1665
|
params = get_streams_params(connection=self.artifacts_store)
|
1649
1666
|
return self.client.runs_v1.delete_run_artifacts(
|
1650
1667
|
namespace=self.namespace,
|
@@ -1667,6 +1684,8 @@ class RunClient:
|
|
1667
1684
|
"""
|
1668
1685
|
if not self.settings:
|
1669
1686
|
self.refresh_data()
|
1687
|
+
self._use_agent_host()
|
1688
|
+
|
1670
1689
|
params = get_streams_params(connection=self.artifacts_store)
|
1671
1690
|
return self.client.runs_v1.get_run_artifacts_tree(
|
1672
1691
|
namespace=self.namespace,
|
@@ -2117,9 +2136,9 @@ class RunClient:
|
|
2117
2136
|
abspath = filepath if is_abs() else os.path.abspath(filepath)
|
2118
2137
|
|
2119
2138
|
for_patterns = []
|
2120
|
-
if getattr(self, "_artifacts_path"):
|
2139
|
+
if getattr(self, "_artifacts_path", None):
|
2121
2140
|
for_patterns.append(getattr(self, "_artifacts_path"))
|
2122
|
-
if getattr(self, "_store_path"):
|
2141
|
+
if getattr(self, "_store_path", None):
|
2123
2142
|
for_patterns.append(getattr(self, "_store_path"))
|
2124
2143
|
context_root = (
|
2125
2144
|
ctx_paths.CONTEXT_OFFLINE_ROOT
|
@@ -33,7 +33,9 @@ class RayJobContextsManager(BaseContextsManager):
|
|
33
33
|
connection_by_names=connection_by_names,
|
34
34
|
)
|
35
35
|
|
36
|
-
|
36
|
+
data = {
|
37
37
|
"head": _get_replica(job.head),
|
38
|
-
"workers": {wn: _get_replica(job.workers[wn]) for wn in job.workers},
|
39
38
|
}
|
39
|
+
if job.workers:
|
40
|
+
data["workers"] = {wn: _get_replica(job.workers[wn]) for wn in job.workers}
|
41
|
+
return data
|
@@ -5,7 +5,7 @@ from clipped.utils.strings import validate_slug
|
|
5
5
|
|
6
6
|
from polyaxon._constants.globals import DEFAULT
|
7
7
|
from polyaxon._env_vars.getters.user import get_local_owner
|
8
|
-
from polyaxon._utils.fqn_utils import get_entity_info
|
8
|
+
from polyaxon._utils.fqn_utils import get_entity_info, split_owner_team_space
|
9
9
|
from polyaxon.exceptions import PolyaxonClientException, PolyaxonSchemaError
|
10
10
|
|
11
11
|
|
@@ -31,6 +31,8 @@ def resolve_entity_info(entity: str, entity_name: str, is_cli: bool = False):
|
|
31
31
|
if not owner:
|
32
32
|
owner = settings.AUTH_CONFIG.username if settings.AUTH_CONFIG else None
|
33
33
|
|
34
|
+
owner, team = split_owner_team_space(owner)
|
35
|
+
|
34
36
|
if not all([owner, entity_value]):
|
35
37
|
message = "Please provide a valid {}.".format(entity_name)
|
36
38
|
if is_cli:
|
@@ -49,4 +51,4 @@ def resolve_entity_info(entity: str, entity_name: str, is_cli: bool = False):
|
|
49
51
|
entity_name, entity_value
|
50
52
|
)
|
51
53
|
)
|
52
|
-
return owner, entity_value
|
54
|
+
return owner, team, entity_value
|
@@ -7,7 +7,7 @@ from polyaxon._constants.globals import DEFAULT
|
|
7
7
|
from polyaxon._env_vars.getters.user import get_local_owner
|
8
8
|
from polyaxon._managers.project import ProjectConfigManager
|
9
9
|
from polyaxon._utils.cache import get_local_project
|
10
|
-
from polyaxon._utils.fqn_utils import get_entity_info
|
10
|
+
from polyaxon._utils.fqn_utils import get_entity_info, split_owner_team_space
|
11
11
|
from polyaxon.exceptions import PolyaxonClientException, PolyaxonSchemaError
|
12
12
|
|
13
13
|
|
@@ -52,6 +52,8 @@ def get_project_or_local(project=None, is_cli: bool = False):
|
|
52
52
|
if not owner and (not settings.CLI_CONFIG or settings.CLI_CONFIG.is_community):
|
53
53
|
owner = DEFAULT
|
54
54
|
|
55
|
+
owner, team = split_owner_team_space(owner)
|
56
|
+
|
55
57
|
if not all([owner, project_name]):
|
56
58
|
error_message = get_project_error_message(owner, project_name)
|
57
59
|
if is_cli:
|
@@ -79,4 +81,4 @@ def get_project_or_local(project=None, is_cli: bool = False):
|
|
79
81
|
sys.exit(1)
|
80
82
|
else:
|
81
83
|
raise PolyaxonSchemaError(error_message)
|
82
|
-
return owner, project_name
|
84
|
+
return owner, team, project_name
|
@@ -37,9 +37,9 @@ def get_run_or_local(run_uuid=None, is_cli: bool = False):
|
|
37
37
|
|
38
38
|
|
39
39
|
def get_project_run_or_local(project=None, run_uuid=None, is_cli: bool = True):
|
40
|
-
|
40
|
+
owner, team, project_name = get_project_or_local(project, is_cli=is_cli)
|
41
41
|
run_uuid = get_run_or_local(run_uuid, is_cli=is_cli)
|
42
|
-
return
|
42
|
+
return owner, team, project_name, run_uuid
|
43
43
|
|
44
44
|
|
45
45
|
def get_collect_artifacts(arg: Optional[bool] = None, default: Optional[bool] = None):
|
polyaxon/_env_vars/keys.py
CHANGED
@@ -141,6 +141,7 @@ ENV_KEYS_PROXY_AUTH_USE_RESOLVER = "POLYAXON_PROXY_AUTH_USE_RESOLVER"
|
|
141
141
|
ENV_KEYS_PROXY_HAS_FORWARD_PROXY = "POLYAXON_PROXY_HAS_FORWARD_PROXY"
|
142
142
|
ENV_KEYS_PROXY_FORWARD_PROXY_PORT = "POLYAXON_PROXY_FORWARD_PROXY_PORT"
|
143
143
|
ENV_KEYS_PROXY_FORWARD_PROXY_HOST = "POLYAXON_PROXY_FORWARD_PROXY_HOST"
|
144
|
+
ENV_KEYS_PROXY_FORWARD_PROXY_PROTOCOL = "POLYAXON_PROXY_FORWARD_PROXY_PROTOCOL"
|
144
145
|
ENV_KEYS_PROXY_FORWARD_PROXY_KIND = "POLYAXON_PROXY_FORWARD_PROXY_KIND"
|
145
146
|
ENV_KEYS_UI_IN_SANDBOX = "POLYAXON_UI_IN_SANDBOX"
|
146
147
|
ENV_KEYS_UI_ADMIN_ENABLED = "POLYAXON_UI_ADMIN_ENABLED"
|
@@ -37,14 +37,17 @@ def requests_gpu(resources: k8s_schemas.V1ResourceRequirements) -> bool:
|
|
37
37
|
if not resources:
|
38
38
|
return False
|
39
39
|
|
40
|
+
if not isinstance(resources, k8s_schemas.V1ResourceRequirements):
|
41
|
+
resources = k8s_schemas.V1ResourceRequirements(**resources)
|
42
|
+
|
40
43
|
if resources.requests:
|
41
|
-
for key in resources.requests.
|
42
|
-
if "gpu" in key:
|
44
|
+
for key, val in resources.requests.items():
|
45
|
+
if "gpu" in key and val is not None and val > 0:
|
43
46
|
return True
|
44
47
|
|
45
48
|
if resources.limits:
|
46
|
-
for key in resources.limits.
|
47
|
-
if "gpu" in key:
|
49
|
+
for key, val in resources.limits.items():
|
50
|
+
if "gpu" in key and val is not None and val > 0:
|
48
51
|
return True
|
49
52
|
|
50
53
|
return False
|
@@ -58,7 +58,9 @@ class RayJobConverter(RayJobMixin, BaseConverter):
|
|
58
58
|
config=compiled_operation.plugins, auth=default_auth
|
59
59
|
)
|
60
60
|
head = _get_replica(job.head)
|
61
|
-
workers =
|
61
|
+
workers = None
|
62
|
+
if job.workers:
|
63
|
+
workers = {n: _get_replica(w) for n, w in job.workers.items()}
|
62
64
|
labels = self.get_labels(version=pkg.VERSION, labels={})
|
63
65
|
|
64
66
|
return get_ray_job_custom_resource(
|
@@ -68,7 +70,7 @@ class RayJobConverter(RayJobMixin, BaseConverter):
|
|
68
70
|
workers=workers,
|
69
71
|
entrypoint=job.entrypoint,
|
70
72
|
metadata=job.metadata,
|
71
|
-
runtime_env=
|
73
|
+
runtime_env=orjson_dumps(job.runtime_env),
|
72
74
|
ray_version=job.ray_version,
|
73
75
|
termination=compiled_operation.termination,
|
74
76
|
collect_logs=plugins.collect_logs,
|
@@ -46,7 +46,7 @@ def set_notify(custom_object: Dict, notifications: List[V1Notification]) -> Dict
|
|
46
46
|
def set_clean_pod_policy(template_spec: Dict, clean_pod_policy: str) -> Dict:
|
47
47
|
if not clean_pod_policy:
|
48
48
|
# Sets default clean pod policy
|
49
|
-
clean_pod_policy = "
|
49
|
+
clean_pod_policy = "None"
|
50
50
|
|
51
51
|
template_spec["cleanPodPolicy"] = clean_pod_policy.capitalize()
|
52
52
|
return template_spec
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
from polyaxon._local_process.converter.base.base import BaseConverter
|
@@ -0,0 +1,140 @@
|
|
1
|
+
from typing import Dict, Iterable, List, Optional, Union
|
2
|
+
|
3
|
+
from polyaxon import settings
|
4
|
+
from polyaxon._auxiliaries import V1PolyaxonSidecarContainer
|
5
|
+
from polyaxon._connections import V1Connection, V1ConnectionResource
|
6
|
+
from polyaxon._flow import V1Environment, V1Init, V1Plugins
|
7
|
+
from polyaxon._k8s import k8s_schemas
|
8
|
+
from polyaxon._local_process import process_types
|
9
|
+
from polyaxon._local_process.converter.base.containers import ContainerMixin
|
10
|
+
from polyaxon._local_process.converter.base.env_vars import EnvMixin
|
11
|
+
from polyaxon._local_process.converter.base.init import InitConverter
|
12
|
+
from polyaxon._local_process.converter.base.main import MainConverter
|
13
|
+
from polyaxon._local_process.converter.base.mounts import MountsMixin
|
14
|
+
from polyaxon._runner.converter import BaseConverter as _BaseConverter
|
15
|
+
from polyaxon._runner.kinds import RunnerKind
|
16
|
+
from polyaxon.exceptions import PolyaxonConverterError
|
17
|
+
|
18
|
+
|
19
|
+
class BaseConverter(
|
20
|
+
MainConverter, InitConverter, ContainerMixin, EnvMixin, MountsMixin, _BaseConverter
|
21
|
+
):
|
22
|
+
RUNNER_KIND = RunnerKind.PROCESS
|
23
|
+
|
24
|
+
@classmethod
|
25
|
+
def _get_sidecar_container(
|
26
|
+
cls,
|
27
|
+
container_id: str,
|
28
|
+
polyaxon_sidecar: V1PolyaxonSidecarContainer,
|
29
|
+
env: List[process_types.V1EnvVar],
|
30
|
+
artifacts_store: V1Connection,
|
31
|
+
plugins: V1Plugins,
|
32
|
+
run_path: Optional[str],
|
33
|
+
) -> Optional[process_types.V1Container]:
|
34
|
+
return None
|
35
|
+
|
36
|
+
@classmethod
|
37
|
+
def _k8s_to_process_env_var(
|
38
|
+
cls,
|
39
|
+
env_var: List[k8s_schemas.V1EnvVar],
|
40
|
+
) -> List[process_types.V1EnvVar]:
|
41
|
+
if not env_var:
|
42
|
+
return []
|
43
|
+
|
44
|
+
process_env_var = []
|
45
|
+
for item in env_var:
|
46
|
+
if isinstance(item, dict):
|
47
|
+
try:
|
48
|
+
item = k8s_schemas.V1EnvVar(**item)
|
49
|
+
except (ValueError, TypeError) as e:
|
50
|
+
raise PolyaxonConverterError(
|
51
|
+
f"Could not parse env var value `{item}` from the K8S schema in container section"
|
52
|
+
) from e
|
53
|
+
process_env_var.append(cls._get_env_var(name=item.name, value=item.value))
|
54
|
+
|
55
|
+
return process_env_var
|
56
|
+
|
57
|
+
@staticmethod
|
58
|
+
def _new_container(name: str) -> process_types.V1Container:
|
59
|
+
return process_types.V1Container(name=name)
|
60
|
+
|
61
|
+
@classmethod
|
62
|
+
def _ensure_container(
|
63
|
+
cls,
|
64
|
+
container: Union[k8s_schemas.V1Container, process_types.V1Container],
|
65
|
+
volumes: List[k8s_schemas.V1Volume],
|
66
|
+
) -> process_types.V1Container:
|
67
|
+
if not isinstance(container, k8s_schemas.V1Container):
|
68
|
+
return container
|
69
|
+
return process_types.V1Container(
|
70
|
+
name=container.name,
|
71
|
+
command=container.command,
|
72
|
+
args=container.args,
|
73
|
+
env=cls._k8s_to_process_env_var(container.env),
|
74
|
+
working_dir=container.working_dir,
|
75
|
+
)
|
76
|
+
|
77
|
+
def get_replica_resource(
|
78
|
+
self,
|
79
|
+
environment: V1Environment,
|
80
|
+
plugins: V1Plugins,
|
81
|
+
volumes: List[k8s_schemas.V1Volume],
|
82
|
+
init: List[V1Init],
|
83
|
+
sidecars: List[k8s_schemas.V1Container],
|
84
|
+
container: k8s_schemas.V1Container,
|
85
|
+
artifacts_store: V1Connection,
|
86
|
+
connections: List[str],
|
87
|
+
connection_by_names: Dict[str, V1Connection],
|
88
|
+
secrets: Optional[Iterable[V1ConnectionResource]],
|
89
|
+
config_maps: Optional[Iterable[V1ConnectionResource]],
|
90
|
+
kv_env_vars: List[List],
|
91
|
+
default_sa: Optional[str] = None,
|
92
|
+
ports: List[int] = None,
|
93
|
+
) -> List[process_types.V1Container]:
|
94
|
+
volumes = volumes or []
|
95
|
+
init = init or []
|
96
|
+
sidecars = sidecars or []
|
97
|
+
connections = connections or []
|
98
|
+
environment = environment or V1Environment()
|
99
|
+
environment.service_account_name = (
|
100
|
+
environment.service_account_name
|
101
|
+
or default_sa
|
102
|
+
or settings.AGENT_CONFIG.runs_sa
|
103
|
+
)
|
104
|
+
|
105
|
+
init_connections = self.filter_connections_from_init(init=init)
|
106
|
+
|
107
|
+
init_containers = self.get_init_containers(
|
108
|
+
polyaxon_init=self.polyaxon_init,
|
109
|
+
plugins=plugins,
|
110
|
+
artifacts_store=artifacts_store,
|
111
|
+
init_connections=init_connections,
|
112
|
+
init_containers=self.filter_containers_from_init(init=init),
|
113
|
+
connection_by_names=connection_by_names,
|
114
|
+
log_level=plugins.log_level,
|
115
|
+
volumes=volumes,
|
116
|
+
)
|
117
|
+
|
118
|
+
sidecar_containers = self.get_sidecar_containers(
|
119
|
+
polyaxon_sidecar=self.polyaxon_sidecar,
|
120
|
+
plugins=plugins,
|
121
|
+
artifacts_store=artifacts_store,
|
122
|
+
sidecar_containers=sidecars,
|
123
|
+
log_level=plugins.log_level,
|
124
|
+
volumes=volumes,
|
125
|
+
)
|
126
|
+
|
127
|
+
main_container = self.get_main_container(
|
128
|
+
main_container=self._ensure_container(container, volumes=volumes),
|
129
|
+
plugins=plugins,
|
130
|
+
artifacts_store=artifacts_store,
|
131
|
+
connections=connections,
|
132
|
+
init_connections=init_connections,
|
133
|
+
connection_by_names=connection_by_names,
|
134
|
+
secrets=secrets,
|
135
|
+
config_maps=config_maps,
|
136
|
+
ports=ports,
|
137
|
+
kv_env_vars=kv_env_vars,
|
138
|
+
)
|
139
|
+
|
140
|
+
return init_containers + sidecar_containers + [main_container]
|