polyaxon 2.1.7.post1__py3-none-any.whl → 2.2.0__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 +42 -23
- 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/_utils/fqn_utils.py +25 -2
- polyaxon/pkg.py +1 -1
- {polyaxon-2.1.7.post1.dist-info → polyaxon-2.2.0.dist-info}/METADATA +2 -2
- {polyaxon-2.1.7.post1.dist-info → polyaxon-2.2.0.dist-info}/RECORD +57 -40
- {polyaxon-2.1.7.post1.dist-info → polyaxon-2.2.0.dist-info}/LICENSE +0 -0
- {polyaxon-2.1.7.post1.dist-info → polyaxon-2.2.0.dist-info}/WHEEL +0 -0
- {polyaxon-2.1.7.post1.dist-info → polyaxon-2.2.0.dist-info}/entry_points.txt +0 -0
- {polyaxon-2.1.7.post1.dist-info → polyaxon-2.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
from typing import Any, Dict, List, Optional
|
2
|
+
|
3
|
+
from clipped.utils.lists import to_list
|
4
|
+
from clipped.utils.sanitizers import sanitize_value
|
5
|
+
|
6
|
+
from polyaxon._containers.names import sanitize_container_name
|
7
|
+
from polyaxon._local_process import process_types
|
8
|
+
from polyaxon._runner.converter import BaseConverter
|
9
|
+
from polyaxon._runner.converter.common.containers import sanitize_container_command_args
|
10
|
+
|
11
|
+
|
12
|
+
class ContainerMixin(BaseConverter):
|
13
|
+
@classmethod
|
14
|
+
def _patch_container(
|
15
|
+
cls,
|
16
|
+
container: process_types.V1Container,
|
17
|
+
name: Optional[str] = None,
|
18
|
+
command: Optional[List[str]] = None,
|
19
|
+
args: Optional[List[str]] = None,
|
20
|
+
env: Optional[List[process_types.V1EnvVar]] = None,
|
21
|
+
env_from: Optional[List[Any]] = None,
|
22
|
+
**kwargs,
|
23
|
+
) -> process_types.V1Container:
|
24
|
+
container.name = sanitize_container_name(name or container.name)
|
25
|
+
container.env = to_list(container.env, check_none=True) + to_list(
|
26
|
+
env, check_none=True
|
27
|
+
)
|
28
|
+
if not any([container.command, container.args]):
|
29
|
+
container.command = command
|
30
|
+
container.args = args
|
31
|
+
|
32
|
+
return cls._sanitize_container(container)
|
33
|
+
|
34
|
+
@staticmethod
|
35
|
+
def _sanitize_container_env(
|
36
|
+
env: List[process_types.V1EnvVar],
|
37
|
+
) -> List[process_types.V1EnvVar]:
|
38
|
+
def sanitize_env_dict(d: Dict):
|
39
|
+
return process_types.V1EnvVar(
|
40
|
+
__root__={
|
41
|
+
d_k: sanitize_value(d_v, handle_dict=False)
|
42
|
+
for d_k, d_v in d.items()
|
43
|
+
}
|
44
|
+
)
|
45
|
+
|
46
|
+
results = []
|
47
|
+
for e in env or []:
|
48
|
+
if isinstance(e, dict):
|
49
|
+
e = sanitize_env_dict(e)
|
50
|
+
results.append(e)
|
51
|
+
elif isinstance(e, tuple):
|
52
|
+
if e[1] is not None:
|
53
|
+
e = process_types.V1EnvVar(
|
54
|
+
__root__=(e[0], sanitize_value(e[1], handle_dict=False))
|
55
|
+
)
|
56
|
+
results.append(e)
|
57
|
+
elif isinstance(e, process_types.V1EnvVar):
|
58
|
+
results.append(e)
|
59
|
+
|
60
|
+
return results
|
61
|
+
|
62
|
+
@classmethod
|
63
|
+
def _sanitize_container(
|
64
|
+
cls,
|
65
|
+
container: process_types.V1Container,
|
66
|
+
) -> process_types.V1Container:
|
67
|
+
container = sanitize_container_command_args(container)
|
68
|
+
container.env = cls._sanitize_container_env(container.env)
|
69
|
+
return container
|
@@ -0,0 +1,253 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from typing import Any, Iterable, List, Optional
|
4
|
+
|
5
|
+
import orjson
|
6
|
+
|
7
|
+
from clipped.utils.enums import get_enum_value
|
8
|
+
from clipped.utils.json import orjson_dumps, orjson_loads
|
9
|
+
from clipped.utils.lists import to_list
|
10
|
+
|
11
|
+
from polyaxon import settings
|
12
|
+
from polyaxon._connections import V1ConnectionResource
|
13
|
+
from polyaxon._env_vars.keys import (
|
14
|
+
ENV_KEYS_API_VERSION,
|
15
|
+
ENV_KEYS_AUTH_TOKEN,
|
16
|
+
ENV_KEYS_AUTHENTICATION_TYPE,
|
17
|
+
ENV_KEYS_HAS_PROCESS_SIDECAR,
|
18
|
+
ENV_KEYS_HEADER,
|
19
|
+
ENV_KEYS_HEADER_SERVICE,
|
20
|
+
ENV_KEYS_HOST,
|
21
|
+
ENV_KEYS_IS_MANAGED,
|
22
|
+
ENV_KEYS_K8S_NAMESPACE,
|
23
|
+
ENV_KEYS_K8S_NODE_NAME,
|
24
|
+
ENV_KEYS_K8S_POD_ID,
|
25
|
+
ENV_KEYS_LOG_LEVEL,
|
26
|
+
ENV_KEYS_SECRET_INTERNAL_TOKEN,
|
27
|
+
ENV_KEYS_SECRET_KEY,
|
28
|
+
)
|
29
|
+
from polyaxon._local_process import process_types
|
30
|
+
from polyaxon._runner.converter import BaseConverter
|
31
|
+
from polyaxon._services.headers import PolyaxonServiceHeaders
|
32
|
+
from polyaxon.api import VERSION_V1
|
33
|
+
from polyaxon.exceptions import PolyaxonConverterError
|
34
|
+
|
35
|
+
|
36
|
+
class EnvMixin(BaseConverter):
|
37
|
+
@staticmethod
|
38
|
+
def _get_env_var(name: str, value: Any) -> process_types.V1EnvVar:
|
39
|
+
if not isinstance(value, str):
|
40
|
+
try:
|
41
|
+
value = orjson_dumps(value)
|
42
|
+
except (ValueError, TypeError) as e:
|
43
|
+
raise PolyaxonConverterError(e)
|
44
|
+
|
45
|
+
return process_types.V1EnvVar(__root__=(name, value))
|
46
|
+
|
47
|
+
@staticmethod
|
48
|
+
def _get_from_json_resource(
|
49
|
+
resource: V1ConnectionResource,
|
50
|
+
) -> List[process_types.V1EnvVar]:
|
51
|
+
if not resource or resource.items or resource.mount_path:
|
52
|
+
return []
|
53
|
+
|
54
|
+
secret = os.environ.get(resource.name)
|
55
|
+
if not secret:
|
56
|
+
return []
|
57
|
+
try:
|
58
|
+
secret_value = orjson_loads(secret)
|
59
|
+
except Exception as e:
|
60
|
+
raise PolyaxonConverterError from e
|
61
|
+
|
62
|
+
return [process_types.V1EnvVar(__root__=k) for k in (secret_value.items())]
|
63
|
+
|
64
|
+
@classmethod
|
65
|
+
def _get_env_from_json_resources(
|
66
|
+
cls,
|
67
|
+
resources: Iterable[V1ConnectionResource],
|
68
|
+
) -> List[process_types.V1EnvVar]:
|
69
|
+
resources = resources or []
|
70
|
+
results = []
|
71
|
+
for resource in resources:
|
72
|
+
results += cls._get_from_json_resource(resource=resource)
|
73
|
+
return [r for r in results if r]
|
74
|
+
|
75
|
+
@staticmethod
|
76
|
+
def _get_item_from_json_resource(
|
77
|
+
key: str, resource_ref_name: str
|
78
|
+
) -> Optional[process_types.V1EnvVar]:
|
79
|
+
secret = os.environ.get(resource_ref_name)
|
80
|
+
if not secret:
|
81
|
+
return None
|
82
|
+
try:
|
83
|
+
secret_value = orjson_loads(secret)
|
84
|
+
except orjson.JSONDecodeError:
|
85
|
+
return process_types.V1EnvVar(__root__=(key, secret))
|
86
|
+
|
87
|
+
value = secret_value.get(key)
|
88
|
+
return process_types.V1EnvVar(__root__=(key, value))
|
89
|
+
|
90
|
+
@classmethod
|
91
|
+
def _get_items_from_json_resource(
|
92
|
+
cls,
|
93
|
+
resource: V1ConnectionResource,
|
94
|
+
) -> List[process_types.V1EnvVar]:
|
95
|
+
items_from = []
|
96
|
+
if not resource or not resource.items:
|
97
|
+
return items_from
|
98
|
+
|
99
|
+
try:
|
100
|
+
secret_value = orjson_loads(resource.name)
|
101
|
+
except orjson.JSONDecodeError as e:
|
102
|
+
return items_from
|
103
|
+
|
104
|
+
for item in resource.items:
|
105
|
+
value = secret_value.get(item)
|
106
|
+
if value:
|
107
|
+
items_from.append(process_types.V1EnvVar(__root__=(item, value)))
|
108
|
+
return items_from
|
109
|
+
|
110
|
+
@classmethod
|
111
|
+
def _get_env_vars_from_resources(
|
112
|
+
cls,
|
113
|
+
resources: Iterable[V1ConnectionResource],
|
114
|
+
) -> List[process_types.V1EnvVar]:
|
115
|
+
resources = resources or []
|
116
|
+
env_vars = []
|
117
|
+
for secret in resources:
|
118
|
+
env_vars += cls._get_items_from_json_resource(resource=secret)
|
119
|
+
return env_vars
|
120
|
+
|
121
|
+
@classmethod
|
122
|
+
def _get_env_vars_from_k8s_resources(
|
123
|
+
cls,
|
124
|
+
secrets: Iterable[V1ConnectionResource],
|
125
|
+
config_maps: Iterable[V1ConnectionResource],
|
126
|
+
) -> List[process_types.V1EnvVar]:
|
127
|
+
resources = to_list(secrets, check_none=True) + to_list(
|
128
|
+
config_maps, check_none=True
|
129
|
+
)
|
130
|
+
return cls._get_env_vars_from_resources(resources=resources)
|
131
|
+
|
132
|
+
@classmethod
|
133
|
+
def _get_additional_env_vars(cls) -> List[process_types.V1EnvVar]:
|
134
|
+
return [cls._get_env_var(name=ENV_KEYS_HAS_PROCESS_SIDECAR, value=True)]
|
135
|
+
|
136
|
+
@classmethod
|
137
|
+
def _get_base_env_vars(
|
138
|
+
cls,
|
139
|
+
namespace: str,
|
140
|
+
resource_name: str,
|
141
|
+
use_proxy_env_vars_use_in_ops: bool,
|
142
|
+
log_level: Optional[str] = None,
|
143
|
+
) -> List[process_types.V1EnvVar]:
|
144
|
+
env = [
|
145
|
+
cls._get_env_var(name=ENV_KEYS_K8S_NODE_NAME, value="process-agent"),
|
146
|
+
cls._get_env_var(name=ENV_KEYS_K8S_NAMESPACE, value=namespace),
|
147
|
+
cls._get_env_var(name=ENV_KEYS_K8S_POD_ID, value=resource_name),
|
148
|
+
]
|
149
|
+
if log_level:
|
150
|
+
env.append(cls._get_env_var(name=ENV_KEYS_LOG_LEVEL, value=log_level))
|
151
|
+
env += cls._get_proxy_env_vars(use_proxy_env_vars_use_in_ops)
|
152
|
+
return env
|
153
|
+
|
154
|
+
def _get_service_env_vars(
|
155
|
+
self,
|
156
|
+
service_header: str,
|
157
|
+
header: Optional[str] = PolyaxonServiceHeaders.SERVICE,
|
158
|
+
include_secret_key: bool = False,
|
159
|
+
include_internal_token: bool = False,
|
160
|
+
include_agent_token: bool = False,
|
161
|
+
authentication_type: Optional[str] = None,
|
162
|
+
external_host: bool = False,
|
163
|
+
log_level: Optional[str] = None,
|
164
|
+
polyaxon_default_secret_ref: Optional[str] = None,
|
165
|
+
polyaxon_agent_secret_ref: Optional[str] = None,
|
166
|
+
api_version: Optional[str] = None,
|
167
|
+
use_proxy_env_vars_use_in_ops: Optional[bool] = None,
|
168
|
+
) -> List[process_types.V1EnvVar]:
|
169
|
+
api_host = self.get_api_host(external_host)
|
170
|
+
polyaxon_default_secret_ref = (
|
171
|
+
polyaxon_default_secret_ref or settings.AGENT_CONFIG.app_secret_name
|
172
|
+
)
|
173
|
+
polyaxon_agent_secret_ref = (
|
174
|
+
polyaxon_agent_secret_ref or settings.AGENT_CONFIG.agent_secret_name
|
175
|
+
)
|
176
|
+
# TODO: Add support for local CLI auth
|
177
|
+
use_proxy_env_vars_use_in_ops = (
|
178
|
+
use_proxy_env_vars_use_in_ops
|
179
|
+
if use_proxy_env_vars_use_in_ops is not None
|
180
|
+
else settings.AGENT_CONFIG.use_proxy_env_vars_use_in_ops
|
181
|
+
)
|
182
|
+
api_version = api_version or VERSION_V1
|
183
|
+
env_vars = self._get_base_env_vars(
|
184
|
+
namespace=self.namespace,
|
185
|
+
resource_name=self.resource_name,
|
186
|
+
use_proxy_env_vars_use_in_ops=use_proxy_env_vars_use_in_ops,
|
187
|
+
) + [
|
188
|
+
self._get_env_var(name=ENV_KEYS_HOST, value=api_host),
|
189
|
+
self._get_env_var(name=ENV_KEYS_IS_MANAGED, value=True),
|
190
|
+
self._get_env_var(name=ENV_KEYS_API_VERSION, value=api_version),
|
191
|
+
self._get_run_instance_env_var(self.run_instance),
|
192
|
+
]
|
193
|
+
if log_level:
|
194
|
+
env_vars.append(self._get_env_var(name=ENV_KEYS_LOG_LEVEL, value=log_level))
|
195
|
+
if header:
|
196
|
+
env_vars.append(
|
197
|
+
self._get_env_var(
|
198
|
+
name=ENV_KEYS_HEADER,
|
199
|
+
value=PolyaxonServiceHeaders.get_header(header),
|
200
|
+
)
|
201
|
+
)
|
202
|
+
if service_header:
|
203
|
+
env_vars += to_list(
|
204
|
+
self._get_env_var(
|
205
|
+
name=ENV_KEYS_HEADER_SERVICE, value=get_enum_value(service_header)
|
206
|
+
),
|
207
|
+
)
|
208
|
+
if include_secret_key:
|
209
|
+
env_vars += to_list(
|
210
|
+
self._get_item_from_json_resource(
|
211
|
+
key=ENV_KEYS_SECRET_KEY,
|
212
|
+
resource_ref_name=polyaxon_default_secret_ref,
|
213
|
+
),
|
214
|
+
check_none=True,
|
215
|
+
)
|
216
|
+
internal = False
|
217
|
+
if include_internal_token and polyaxon_default_secret_ref:
|
218
|
+
internal = True
|
219
|
+
env_vars += to_list(
|
220
|
+
self._get_item_from_json_resource(
|
221
|
+
key=ENV_KEYS_SECRET_INTERNAL_TOKEN,
|
222
|
+
resource_ref_name=polyaxon_default_secret_ref,
|
223
|
+
),
|
224
|
+
check_none=True,
|
225
|
+
)
|
226
|
+
if include_agent_token:
|
227
|
+
if internal:
|
228
|
+
raise PolyaxonConverterError(
|
229
|
+
"A service cannot have internal token and agent token."
|
230
|
+
)
|
231
|
+
if polyaxon_agent_secret_ref:
|
232
|
+
env_vars += to_list(
|
233
|
+
self._get_item_from_json_resource(
|
234
|
+
key=ENV_KEYS_AUTH_TOKEN,
|
235
|
+
resource_ref_name=polyaxon_agent_secret_ref,
|
236
|
+
),
|
237
|
+
check_none=True,
|
238
|
+
)
|
239
|
+
elif settings.CLIENT_CONFIG.token:
|
240
|
+
env_vars += to_list(
|
241
|
+
self._get_env_var(
|
242
|
+
name=ENV_KEYS_AUTH_TOKEN, value=settings.CLIENT_CONFIG.token
|
243
|
+
),
|
244
|
+
check_none=True,
|
245
|
+
)
|
246
|
+
if authentication_type:
|
247
|
+
env_vars += to_list(
|
248
|
+
self._get_env_var(
|
249
|
+
name=ENV_KEYS_AUTHENTICATION_TYPE, value=authentication_type
|
250
|
+
),
|
251
|
+
check_none=True,
|
252
|
+
)
|
253
|
+
return env_vars
|