polyaxon 2.0.0rc49__py3-none-any.whl → 2.4.0rc1__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 (177) hide show
  1. polyaxon/_auxiliaries/cleaner.py +8 -3
  2. polyaxon/_auxiliaries/init.py +7 -2
  3. polyaxon/_auxiliaries/notifier.py +8 -2
  4. polyaxon/_auxiliaries/sidecar.py +30 -2
  5. polyaxon/_cli/artifacts.py +96 -11
  6. polyaxon/_cli/components.py +96 -11
  7. polyaxon/_cli/config.py +118 -22
  8. polyaxon/_cli/dashboard.py +15 -2
  9. polyaxon/_cli/init.py +1 -1
  10. polyaxon/_cli/models.py +96 -11
  11. polyaxon/_cli/operations.py +267 -90
  12. polyaxon/_cli/project_versions.py +139 -6
  13. polyaxon/_cli/projects.py +23 -9
  14. polyaxon/_cli/run.py +37 -9
  15. polyaxon/_cli/services/agent.py +2 -2
  16. polyaxon/_cli/services/clean_artifacts.py +1 -1
  17. polyaxon/_cli/services/sidecar.py +8 -1
  18. polyaxon/_client/client.py +17 -0
  19. polyaxon/_client/mixin.py +39 -0
  20. polyaxon/_client/project.py +218 -23
  21. polyaxon/_client/run.py +131 -33
  22. polyaxon/_compiler/contexts/contexts.py +2 -2
  23. polyaxon/_compiler/contexts/ray_job.py +4 -2
  24. polyaxon/_compiler/resolver/agent.py +12 -2
  25. polyaxon/_compiler/resolver/runtime.py +2 -2
  26. polyaxon/_contexts/paths.py +4 -7
  27. polyaxon/_deploy/operators/compose.py +1 -27
  28. polyaxon/_deploy/schemas/deployment.py +4 -1
  29. polyaxon/_deploy/schemas/intervals.py +0 -7
  30. polyaxon/_deploy/schemas/proxy.py +1 -0
  31. polyaxon/_deploy/schemas/service.py +11 -1
  32. polyaxon/_docker/converter/base/base.py +8 -0
  33. polyaxon/_docker/executor.py +10 -4
  34. polyaxon/_env_vars/getters/owner_entity.py +4 -2
  35. polyaxon/_env_vars/getters/project.py +4 -2
  36. polyaxon/_env_vars/getters/run.py +5 -2
  37. polyaxon/_env_vars/keys.py +7 -1
  38. polyaxon/_flow/__init__.py +2 -0
  39. polyaxon/_flow/builds/__init__.py +19 -6
  40. polyaxon/_flow/component/base.py +1 -0
  41. polyaxon/_flow/component/component.py +14 -0
  42. polyaxon/_flow/environment/__init__.py +8 -8
  43. polyaxon/_flow/hooks/__init__.py +19 -6
  44. polyaxon/_flow/init/__init__.py +6 -6
  45. polyaxon/_flow/matrix/iterative.py +0 -1
  46. polyaxon/_flow/matrix/tuner.py +18 -6
  47. polyaxon/_flow/operations/operation.py +44 -17
  48. polyaxon/_flow/plugins/__init__.py +6 -0
  49. polyaxon/_flow/run/__init__.py +2 -2
  50. polyaxon/_flow/run/dag.py +2 -2
  51. polyaxon/_flow/run/dask/dask.py +0 -1
  52. polyaxon/_flow/run/dask/replica.py +3 -3
  53. polyaxon/_flow/run/enums.py +5 -0
  54. polyaxon/_flow/run/job.py +4 -4
  55. polyaxon/_flow/run/kubeflow/mpi_job.py +1 -2
  56. polyaxon/_flow/run/kubeflow/mx_job.py +1 -2
  57. polyaxon/_flow/run/kubeflow/paddle_job.py +35 -4
  58. polyaxon/_flow/run/kubeflow/pytorch_job.py +51 -5
  59. polyaxon/_flow/run/kubeflow/replica.py +4 -4
  60. polyaxon/_flow/run/kubeflow/scheduling_policy.py +12 -0
  61. polyaxon/_flow/run/kubeflow/tf_job.py +3 -3
  62. polyaxon/_flow/run/kubeflow/xgboost_job.py +1 -2
  63. polyaxon/_flow/run/ray/ray.py +2 -3
  64. polyaxon/_flow/run/ray/replica.py +3 -3
  65. polyaxon/_flow/run/service.py +4 -4
  66. polyaxon/_fs/fs.py +7 -2
  67. polyaxon/_fs/utils.py +3 -2
  68. polyaxon/_k8s/converter/base/base.py +2 -1
  69. polyaxon/_k8s/converter/base/main.py +1 -0
  70. polyaxon/_k8s/converter/base/sidecar.py +16 -1
  71. polyaxon/_k8s/converter/common/accelerators.py +7 -4
  72. polyaxon/_k8s/converter/converters/job.py +1 -1
  73. polyaxon/_k8s/converter/converters/kubeflow/paddle_job.py +1 -0
  74. polyaxon/_k8s/converter/converters/kubeflow/pytroch_job.py +2 -0
  75. polyaxon/_k8s/converter/converters/kubeflow/tf_job.py +1 -0
  76. polyaxon/_k8s/converter/converters/ray_job.py +4 -2
  77. polyaxon/_k8s/custom_resources/dask_job.py +3 -0
  78. polyaxon/_k8s/custom_resources/kubeflow/common.py +4 -1
  79. polyaxon/_k8s/custom_resources/kubeflow/paddle_job.py +10 -1
  80. polyaxon/_k8s/custom_resources/kubeflow/pytorch_job.py +14 -1
  81. polyaxon/_k8s/custom_resources/kubeflow/tf_job.py +4 -0
  82. polyaxon/_k8s/custom_resources/ray_job.py +3 -0
  83. polyaxon/_k8s/custom_resources/setter.py +1 -1
  84. polyaxon/_k8s/executor/async_executor.py +2 -0
  85. polyaxon/_k8s/executor/base.py +23 -6
  86. polyaxon/_k8s/logging/async_monitor.py +150 -5
  87. polyaxon/_k8s/manager/async_manager.py +96 -23
  88. polyaxon/_k8s/manager/base.py +4 -0
  89. polyaxon/_k8s/manager/manager.py +282 -134
  90. polyaxon/_local_process/__init__.py +0 -0
  91. polyaxon/_local_process/agent.py +6 -0
  92. polyaxon/_local_process/converter/__init__.py +1 -0
  93. polyaxon/_local_process/converter/base/__init__.py +1 -0
  94. polyaxon/_local_process/converter/base/base.py +140 -0
  95. polyaxon/_local_process/converter/base/containers.py +69 -0
  96. polyaxon/_local_process/converter/base/env_vars.py +253 -0
  97. polyaxon/_local_process/converter/base/init.py +414 -0
  98. polyaxon/_local_process/converter/base/main.py +74 -0
  99. polyaxon/_local_process/converter/base/mounts.py +82 -0
  100. polyaxon/_local_process/converter/converters/__init__.py +8 -0
  101. polyaxon/_local_process/converter/converters/job.py +40 -0
  102. polyaxon/_local_process/converter/converters/service.py +41 -0
  103. polyaxon/_local_process/converter/mixins.py +38 -0
  104. polyaxon/_local_process/executor.py +132 -0
  105. polyaxon/_local_process/process_types.py +39 -0
  106. polyaxon/_managers/agent.py +2 -0
  107. polyaxon/_managers/home.py +2 -1
  108. polyaxon/_operations/tuner.py +1 -0
  109. polyaxon/_polyaxonfile/check.py +2 -0
  110. polyaxon/_polyaxonfile/manager/operations.py +3 -0
  111. polyaxon/_polyaxonfile/manager/workflows.py +2 -0
  112. polyaxon/_polyaxonfile/specs/compiled_operation.py +1 -0
  113. polyaxon/_polyaxonfile/specs/operation.py +1 -0
  114. polyaxon/_polyaxonfile/specs/sections.py +3 -0
  115. polyaxon/_pql/manager.py +1 -1
  116. polyaxon/_runner/agent/async_agent.py +97 -21
  117. polyaxon/_runner/agent/base_agent.py +27 -9
  118. polyaxon/_runner/agent/client.py +15 -1
  119. polyaxon/_runner/agent/sync_agent.py +85 -20
  120. polyaxon/_runner/converter/converter.py +6 -2
  121. polyaxon/_runner/executor.py +13 -7
  122. polyaxon/_schemas/agent.py +27 -1
  123. polyaxon/_schemas/client.py +30 -3
  124. polyaxon/_schemas/installation.py +4 -3
  125. polyaxon/_schemas/lifecycle.py +10 -5
  126. polyaxon/_schemas/log_handler.py +2 -3
  127. polyaxon/_schemas/types/artifacts.py +3 -3
  128. polyaxon/_schemas/types/dockerfile.py +3 -3
  129. polyaxon/_schemas/types/file.py +3 -3
  130. polyaxon/_schemas/types/git.py +3 -3
  131. polyaxon/_schemas/types/tensorboard.py +3 -3
  132. polyaxon/_sdk/api/agents_v1_api.py +1076 -73
  133. polyaxon/_sdk/api/organizations_v1_api.py +371 -10
  134. polyaxon/_sdk/api/project_dashboards_v1_api.py +12 -12
  135. polyaxon/_sdk/api/project_searches_v1_api.py +12 -12
  136. polyaxon/_sdk/api/projects_v1_api.py +221 -44
  137. polyaxon/_sdk/api/runs_v1_api.py +917 -445
  138. polyaxon/_sdk/api/service_accounts_v1_api.py +16 -16
  139. polyaxon/_sdk/api/teams_v1_api.py +2827 -375
  140. polyaxon/_sdk/api/users_v1_api.py +231 -55
  141. polyaxon/_sdk/async_client/api_client.py +4 -0
  142. polyaxon/_sdk/schemas/__init__.py +10 -2
  143. polyaxon/_sdk/schemas/v1_agent.py +2 -1
  144. polyaxon/_sdk/schemas/v1_agent_reconcile_body_request.py +14 -0
  145. polyaxon/_sdk/schemas/v1_artifact_tree.py +1 -1
  146. polyaxon/_sdk/schemas/v1_dashboard_spec.py +4 -0
  147. polyaxon/_sdk/schemas/v1_events_response.py +4 -0
  148. polyaxon/_sdk/schemas/v1_organization.py +1 -0
  149. polyaxon/_sdk/schemas/v1_preset.py +8 -0
  150. polyaxon/_sdk/schemas/v1_project.py +1 -0
  151. polyaxon/_sdk/schemas/v1_project_settings.py +4 -2
  152. polyaxon/_sdk/schemas/v1_run.py +2 -2
  153. polyaxon/_sdk/schemas/v1_run_edge_lineage.py +14 -0
  154. polyaxon/_sdk/schemas/v1_run_edges_graph.py +9 -0
  155. polyaxon/_sdk/schemas/v1_section_spec.py +7 -2
  156. polyaxon/_sdk/schemas/v1_settings_catalog.py +1 -0
  157. polyaxon/_sdk/schemas/v1_team.py +3 -0
  158. polyaxon/_sdk/schemas/v1_user.py +1 -2
  159. polyaxon/_sdk/schemas/v1_user_access.py +17 -0
  160. polyaxon/_services/values.py +1 -0
  161. polyaxon/_sidecar/container/__init__.py +39 -18
  162. polyaxon/_sidecar/container/monitors/__init__.py +1 -0
  163. polyaxon/_sidecar/container/monitors/logs.py +10 -13
  164. polyaxon/_sidecar/container/monitors/spec.py +24 -0
  165. polyaxon/_sidecar/ignore.py +0 -1
  166. polyaxon/_utils/fqn_utils.py +25 -2
  167. polyaxon/client.py +1 -1
  168. polyaxon/pkg.py +1 -1
  169. polyaxon/schemas.py +8 -1
  170. polyaxon/settings.py +6 -0
  171. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/METADATA +43 -43
  172. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/RECORD +176 -155
  173. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/WHEEL +1 -1
  174. polyaxon/_sdk/schemas/v1_project_user_access.py +0 -10
  175. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/LICENSE +0 -0
  176. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/entry_points.txt +0 -0
  177. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,7 @@ from urllib3.exceptions import HTTPError
13
13
  from polyaxon import pkg, settings
14
14
  from polyaxon._env_vars.getters import get_run_info
15
15
  from polyaxon._runner.agent.base_agent import BaseAgent
16
+ from polyaxon._utils.fqn_utils import get_run_instance
16
17
  from polyaxon.client import V1Agent, V1AgentStateResponse
17
18
  from polyaxon.exceptions import ApiException as SDKApiException
18
19
  from polyaxon.exceptions import PolyaxonAgentError, PolyaxonConverterError
@@ -25,13 +26,13 @@ class BaseSyncAgent(BaseAgent):
25
26
  def _enter(self):
26
27
  if not self.client._is_managed:
27
28
  return self
28
- print("Agent is starting.")
29
+ logger.warning("Agent is starting.")
29
30
  try:
30
31
  agent = self.client.get_info()
31
32
  self._check_status(agent)
32
33
  self.sync()
33
34
  self.client.log_agent_running()
34
- print("Agent is running.")
35
+ logger.warning("Agent is running.")
35
36
  return self
36
37
  except (ApiException, SDKApiException, HTTPError) as e:
37
38
  message = "Could not start the agent."
@@ -76,6 +77,49 @@ class BaseSyncAgent(BaseAgent):
76
77
  ),
77
78
  )
78
79
 
80
+ def reconcile(self):
81
+ if (
82
+ now() - self._last_reconciled_at
83
+ ).total_seconds() > self.SLEEP_AGENT_DATA_COLLECT_TIME:
84
+ return
85
+
86
+ # Collect data
87
+ self.collect_agent_data()
88
+
89
+ # Update reconcile
90
+ namespaces = [settings.AGENT_CONFIG.namespace]
91
+ namespaces += settings.AGENT_CONFIG.additional_namespaces or []
92
+ ops = []
93
+ for namespace in namespaces:
94
+ _ops = self.executor.list_ops(namespace=namespace)
95
+ if _ops:
96
+ ops += [
97
+ (
98
+ get_run_instance(
99
+ owner=op["metadata"]["annotations"][
100
+ "operation.polyaxon.com/owner"
101
+ ],
102
+ project=op["metadata"]["annotations"][
103
+ "operation.polyaxon.com/project"
104
+ ],
105
+ run_uuid=op["metadata"]["labels"][
106
+ "app.kubernetes.io/instance"
107
+ ],
108
+ ),
109
+ op["metadata"]["annotations"]["operation.polyaxon.com/kind"],
110
+ op["metadata"]["annotations"]["operation.polyaxon.com/name"],
111
+ namespace,
112
+ )
113
+ for op in _ops
114
+ ]
115
+ if not ops:
116
+ return None
117
+
118
+ logger.info("Reconcile agent.")
119
+ return self.client.reconcile_agent(
120
+ reconcile={"ops": ops},
121
+ )
122
+
79
123
  def start(self):
80
124
  try:
81
125
  with sync_exit_context() as exit_event:
@@ -88,7 +132,9 @@ class BaseSyncAgent(BaseAgent):
88
132
  while not exit_event.wait(timeout=timeout):
89
133
  index += 1
90
134
  self.refresh_executor()
91
- if not self._default_auth:
135
+ if self._default_auth:
136
+ self.reconcile()
137
+ else:
92
138
  self.cron()
93
139
  agent_state = self.process(pool)
94
140
  if not agent_state:
@@ -113,7 +159,7 @@ class BaseSyncAgent(BaseAgent):
113
159
  self.sync_compatible_updates(agent_state.compatible_updates)
114
160
 
115
161
  if agent_state:
116
- logger.info("Starting runs submission process.")
162
+ logger.info("Checking agent state.")
117
163
  else:
118
164
  logger.info("No state was found.")
119
165
  return V1AgentStateResponse.construct()
@@ -180,7 +226,7 @@ class BaseSyncAgent(BaseAgent):
180
226
  )
181
227
  return None
182
228
 
183
- def submit_run(self, run_data: Tuple[str, str, str, str]):
229
+ def submit_run(self, run_data: Tuple[str, str, str, str, str]):
184
230
  run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
185
231
  resource = self.prepare_run_resource(
186
232
  owner_name=run_owner,
@@ -194,7 +240,10 @@ class BaseSyncAgent(BaseAgent):
194
240
 
195
241
  try:
196
242
  self.executor.create(
197
- run_uuid=run_uuid, run_kind=run_data[1], resource=resource
243
+ run_uuid=run_uuid,
244
+ run_kind=run_data[1],
245
+ resource=resource,
246
+ namespace=run_data[4],
198
247
  )
199
248
  except ApiException as e:
200
249
  if e.status == 409:
@@ -217,7 +266,7 @@ class BaseSyncAgent(BaseAgent):
217
266
  )
218
267
 
219
268
  def make_and_create_run(
220
- self, run_data: Tuple[str, str, str, str], default_auth: bool = False
269
+ self, run_data: Tuple[str, str, str, str, str], default_auth: bool = False
221
270
  ):
222
271
  run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
223
272
  resource = self.make_run_resource(
@@ -233,7 +282,10 @@ class BaseSyncAgent(BaseAgent):
233
282
 
234
283
  try:
235
284
  self.executor.create(
236
- run_uuid=run_uuid, run_kind=run_data[1], resource=resource
285
+ run_uuid=run_uuid,
286
+ run_kind=run_data[1],
287
+ resource=resource,
288
+ namespace=run_data[4],
237
289
  )
238
290
  except ApiException as e:
239
291
  if e.status == 409:
@@ -247,7 +299,7 @@ class BaseSyncAgent(BaseAgent):
247
299
  )
248
300
  )
249
301
 
250
- def apply_run(self, run_data: Tuple[str, str, str, str]):
302
+ def apply_run(self, run_data: Tuple[str, str, str, str, str]):
251
303
  run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
252
304
  resource = self.prepare_run_resource(
253
305
  owner_name=run_owner,
@@ -261,7 +313,10 @@ class BaseSyncAgent(BaseAgent):
261
313
 
262
314
  try:
263
315
  self.executor.apply(
264
- run_uuid=run_uuid, run_kind=run_data[1], resource=resource
316
+ run_uuid=run_uuid,
317
+ run_kind=run_data[1],
318
+ resource=resource,
319
+ namespace=run_data[4],
265
320
  )
266
321
  self.client.log_run_running(
267
322
  run_owner=run_owner, run_project=run_project, run_uuid=run_uuid
@@ -270,12 +325,16 @@ class BaseSyncAgent(BaseAgent):
270
325
  self.client.log_run_failed(
271
326
  run_owner=run_owner, run_project=run_project, run_uuid=run_uuid, exc=e
272
327
  )
273
- self.clean_run(run_uuid=run_uuid, run_kind=run_data[1])
328
+ self.clean_run(
329
+ run_uuid=run_uuid, run_kind=run_data[1], namespace=run_data[4]
330
+ )
274
331
 
275
- def check_run(self, run_data: Tuple[str, str]):
332
+ def check_run(self, run_data: Tuple[str, str, str]):
276
333
  run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
277
334
  try:
278
- self.executor.get(run_uuid=run_uuid, run_kind=run_data[1])
335
+ self.executor.get(
336
+ run_uuid=run_uuid, run_kind=run_data[1], namespace=run_data[2]
337
+ )
279
338
  except ApiException as e:
280
339
  if e.status == 404:
281
340
  logger.info(
@@ -285,10 +344,12 @@ class BaseSyncAgent(BaseAgent):
285
344
  run_owner=run_owner, run_project=run_project, run_uuid=run_uuid
286
345
  )
287
346
 
288
- def stop_run(self, run_data: Tuple[str, str]):
347
+ def stop_run(self, run_data: Tuple[str, str, str]):
289
348
  run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
290
349
  try:
291
- self.executor.stop(run_uuid=run_uuid, run_kind=run_data[1])
350
+ self.executor.stop(
351
+ run_uuid=run_uuid, run_kind=run_data[1], namespace=run_data[2]
352
+ )
292
353
  except ApiException as e:
293
354
  if e.status == 404:
294
355
  logger.info("Run does not exist anymore, it could have been stopped.")
@@ -304,16 +365,20 @@ class BaseSyncAgent(BaseAgent):
304
365
  message="Agent failed stopping run.\n",
305
366
  )
306
367
 
307
- def delete_run(self, run_data: Tuple[str, str, str, str]):
368
+ def delete_run(self, run_data: Tuple[str, str, str, str, str]):
308
369
  run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
309
- self.clean_run(run_uuid=run_uuid, run_kind=run_data[1])
370
+ self.clean_run(run_uuid=run_uuid, run_kind=run_data[1], namespace=run_data[4])
310
371
  if run_data[3]:
311
372
  self.make_and_create_run(run_data)
312
373
 
313
- def clean_run(self, run_uuid: str, run_kind: str):
374
+ def clean_run(self, run_uuid: str, run_kind: str, namespace: str = None):
314
375
  try:
315
- self.executor.clean(run_uuid=run_uuid, run_kind=run_kind)
316
- self.executor.stop(run_uuid=run_uuid, run_kind=run_kind)
376
+ self.executor.clean(
377
+ run_uuid=run_uuid, run_kind=run_kind, namespace=namespace
378
+ )
379
+ self.executor.stop(
380
+ run_uuid=run_uuid, run_kind=run_kind, namespace=namespace
381
+ )
317
382
  except ApiException as e:
318
383
  if e.status == 404:
319
384
  logger.info("Run does not exist.")
@@ -711,7 +711,9 @@ class BaseConverter:
711
711
  V1ConnectionKind.is_ssh(connection_spec.kind)
712
712
  and init_connection.git
713
713
  ):
714
- patch_git(connection_spec.schema_, init_connection.git)
714
+ connection_spec.schema_ = patch_git(
715
+ connection_spec.schema_, init_connection.git
716
+ )
715
717
  containers.append(
716
718
  self._get_git_init_container(
717
719
  run_path=self.run_path,
@@ -731,7 +733,9 @@ class BaseConverter:
731
733
  )
732
734
  elif V1ConnectionKind.is_git(connection_spec.kind):
733
735
  if init_connection.git: # Update the default schema
734
- connection_spec.schema_.patch(init_connection.git)
736
+ connection_spec.schema_ = patch_git(
737
+ connection_spec.schema_, init_connection.git
738
+ )
735
739
  containers.append(
736
740
  self._get_git_init_container(
737
741
  run_path=self.run_path,
@@ -50,19 +50,21 @@ class BaseExecutor:
50
50
  self._manager = None
51
51
  return self.manager
52
52
 
53
- def get(self, run_uuid: str, run_kind: str):
53
+ def get(self, run_uuid: str, run_kind: str, namespace: str = None):
54
54
  raise NotImplementedError
55
55
 
56
- def create(self, run_uuid: str, run_kind: str, resource: Any):
56
+ def create(
57
+ self, run_uuid: str, run_kind: str, resource: Any, namespace: str = None
58
+ ):
57
59
  raise NotImplementedError
58
60
 
59
- def apply(self, run_uuid: str, run_kind: str, resource: Any):
61
+ def apply(self, run_uuid: str, run_kind: str, resource: Any, namespace: str = None):
60
62
  raise NotImplementedError
61
63
 
62
- def stop(self, run_uuid: str, run_kind: str):
64
+ def stop(self, run_uuid: str, run_kind: str, namespace: str = None):
63
65
  raise NotImplementedError
64
66
 
65
- def clean(self, run_uuid: str, run_kind: str):
67
+ def clean(self, run_uuid: str, run_kind: str, namespace: str = None):
66
68
  raise NotImplementedError
67
69
 
68
70
  def _clean_temp_execution_path(self, run_uuid: str):
@@ -154,7 +156,7 @@ class BaseExecutor:
154
156
  run_name=run_name,
155
157
  run_uuid=run_uuid,
156
158
  run_path=run_uuid,
157
- namespace=agent_env.namespace,
159
+ namespace=compiled_operation.namespace or agent_env.namespace,
158
160
  compiled_operation=compiled_operation,
159
161
  polyaxon_init=agent_env.polyaxon_init,
160
162
  polyaxon_sidecar=agent_env.polyaxon_sidecar,
@@ -191,7 +193,7 @@ class BaseExecutor:
191
193
  params=operation.params,
192
194
  )
193
195
  return cls.get_resource(
194
- namespace=resolver_obj.namespace,
196
+ namespace=compiled_operation.namespace or resolver_obj.namespace,
195
197
  owner_name=resolver_obj.owner_name,
196
198
  project_name=resolver_obj.project_name,
197
199
  run_name=resolver_obj.run_name,
@@ -223,4 +225,8 @@ class BaseExecutor:
223
225
  run_uuid=response.uuid,
224
226
  run_kind=response.kind,
225
227
  resource=resource,
228
+ namespace=response.settings.namespace if response.settings else None,
226
229
  )
230
+
231
+ def list_ops(self, namespace: str = None):
232
+ raise NotImplementedError
@@ -18,6 +18,7 @@ from polyaxon._connections import V1Connection, V1ConnectionKind, V1HostPathConn
18
18
  from polyaxon._contexts import paths as ctx_paths
19
19
  from polyaxon._env_vars.getters import get_artifacts_store_name
20
20
  from polyaxon._env_vars.keys import (
21
+ ENV_KEYS_ADDITIONAL_NAMESPACES,
21
22
  ENV_KEYS_AGENT_ARTIFACTS_STORE,
22
23
  ENV_KEYS_AGENT_CLEANER,
23
24
  ENV_KEYS_AGENT_CONNECTIONS,
@@ -35,6 +36,8 @@ from polyaxon._env_vars.keys import (
35
36
  ENV_KEYS_ARTIFACTS_STORE_NAME,
36
37
  ENV_KEYS_K8S_APP_SECRET_NAME,
37
38
  ENV_KEYS_K8S_NAMESPACE,
39
+ ENV_KEYS_SINGLE_NAMESPACE,
40
+ ENV_KEYS_WATCH_CLUSTER,
38
41
  )
39
42
  from polyaxon._fs.utils import get_store_path
40
43
  from polyaxon._schemas.base import BaseSchemaModel
@@ -185,6 +188,11 @@ class AgentConfig(BaseAgentConfig):
185
188
  _IDENTIFIER = "agent"
186
189
 
187
190
  is_replica: Optional[bool] = Field(alias=ENV_KEYS_AGENT_IS_REPLICA)
191
+ watch_cluster: Optional[bool] = Field(alias=ENV_KEYS_WATCH_CLUSTER)
192
+ single_namespace: Optional[bool] = Field(alias=ENV_KEYS_SINGLE_NAMESPACE)
193
+ additional_namespaces: Optional[List[StrictStr]] = Field(
194
+ alias=ENV_KEYS_ADDITIONAL_NAMESPACES
195
+ )
188
196
  sidecar: Optional[V1PolyaxonSidecarContainer] = Field(alias=ENV_KEYS_AGENT_SIDECAR)
189
197
  init: Optional[V1PolyaxonInitContainer] = Field(alias=ENV_KEYS_AGENT_INIT)
190
198
  notifier: Optional[V1PolyaxonNotifier] = Field(alias=ENV_KEYS_AGENT_NOTIFIER)
@@ -217,6 +225,24 @@ class AgentConfig(BaseAgentConfig):
217
225
  and "isReplica" in values
218
226
  ):
219
227
  values[ENV_KEYS_AGENT_IS_REPLICA] = values["isReplica"]
228
+ if (
229
+ not values.get("watch_cluster")
230
+ and not values.get(ENV_KEYS_WATCH_CLUSTER)
231
+ and "watchCluster" in values
232
+ ):
233
+ values[ENV_KEYS_WATCH_CLUSTER] = values["watchCluster"]
234
+ if (
235
+ not values.get("single_namespace")
236
+ and not values.get(ENV_KEYS_SINGLE_NAMESPACE)
237
+ and "singleNamespace" in values
238
+ ):
239
+ values[ENV_KEYS_SINGLE_NAMESPACE] = values["singleNamespace"]
240
+ if (
241
+ not values.get("additional_namespace")
242
+ and not values.get(ENV_KEYS_ADDITIONAL_NAMESPACES)
243
+ and "additionalNamespaces" in values
244
+ ):
245
+ values[ENV_KEYS_ADDITIONAL_NAMESPACES] = values["additionalNamespaces"]
220
246
  if (
221
247
  not values.get("use_proxy_env_vars_use_in_ops")
222
248
  and not values.get(ENV_KEYS_AGENT_USE_PROXY_ENV_VARS_IN_OPS)
@@ -312,7 +338,7 @@ class AgentConfig(BaseAgentConfig):
312
338
  "Received an invalid {} `{}`".format(field.alias, v)
313
339
  ) from e
314
340
 
315
- @validator("default_image_pull_secrets", pre=True)
341
+ @validator("additional_namespaces", "default_image_pull_secrets", pre=True)
316
342
  def validate_str_list(cls, v, field):
317
343
  try:
318
344
  return ConfigParser.parse(str)(
@@ -1,3 +1,5 @@
1
+ import os
2
+
1
3
  from typing import Dict, Optional, Union
2
4
 
3
5
  import urllib3
@@ -29,6 +31,7 @@ from polyaxon._env_vars.keys import (
29
31
  ENV_KEYS_NO_API,
30
32
  ENV_KEYS_NO_OP,
31
33
  ENV_KEYS_RETRIES,
34
+ ENV_KEYS_SECRET_INTERNAL_TOKEN,
32
35
  ENV_KEYS_SSL_CA_CERT,
33
36
  ENV_KEYS_TIME_ZONE,
34
37
  ENV_KEYS_TIMEOUT,
@@ -137,6 +140,10 @@ class ClientConfig(BaseSchemaModel):
137
140
  self.client_header["header_name"] = self.header
138
141
  self.client_header["header_value"] = self.header_service
139
142
 
143
+ def get_internal_header(self) -> Dict:
144
+ header = PolyaxonServiceHeaders.get_header(PolyaxonServiceHeaders.INTERNAL)
145
+ return {"header_name": header, "header_value": self.header_service}
146
+
140
147
  def get_full_headers(self, headers=None, auth_key="Authorization") -> Dict:
141
148
  request_headers = {}
142
149
  request_headers.update(headers or {})
@@ -151,7 +158,19 @@ class ClientConfig(BaseSchemaModel):
151
158
  return request_headers
152
159
 
153
160
  @property
154
- def sdk_config(self) -> Configuration:
161
+ def sdk_config(self):
162
+ return self.get_sdk_config()
163
+
164
+ @property
165
+ def internal_sdk_config(self):
166
+ return self.get_sdk_config(
167
+ token=os.environ.get(ENV_KEYS_SECRET_INTERNAL_TOKEN),
168
+ authentication_type=AuthenticationTypes.INTERNAL_TOKEN,
169
+ )
170
+
171
+ def get_sdk_config(
172
+ self, token: str = None, authentication_type: AuthenticationTypes = None
173
+ ) -> Configuration:
155
174
  if not self.host and not self.in_cluster:
156
175
  raise PolyaxonClientException(
157
176
  "Api config requires at least a host if not running in-cluster."
@@ -171,8 +190,10 @@ class ClientConfig(BaseSchemaModel):
171
190
  if self.connection_pool_maxsize:
172
191
  config.connection_pool_maxsize = self.connection_pool_maxsize
173
192
  if self.token:
174
- config.api_key["ApiKey"] = self.token
175
- config.api_key_prefix["ApiKey"] = self.authentication_type
193
+ config.api_key["ApiKey"] = token or self.token
194
+ config.api_key_prefix["ApiKey"] = (
195
+ authentication_type or self.authentication_type
196
+ )
176
197
  return config
177
198
 
178
199
  @property
@@ -181,6 +202,12 @@ class ClientConfig(BaseSchemaModel):
181
202
  config.connection_pool_maxsize = 100
182
203
  return config
183
204
 
205
+ @property
206
+ def async_internal_sdk_config(self) -> Configuration:
207
+ config = self.internal_sdk_config
208
+ config.connection_pool_maxsize = 100
209
+ return config
210
+
184
211
  @classmethod
185
212
  def patch_from(cls, config: "ClientConfig", **kwargs) -> "ClientConfig":
186
213
  data = {**config.to_dict(), **kwargs}
@@ -1,14 +1,15 @@
1
1
  from typing import List, Optional
2
2
 
3
3
  from clipped.compact.pydantic import StrictStr
4
+ from clipped.config.schema import BaseAllowSchemaModel
4
5
 
5
- from polyaxon._schemas.base import BaseSchemaModel
6
6
 
7
-
8
- class V1Installation(BaseSchemaModel):
7
+ class V1Installation(BaseAllowSchemaModel):
9
8
  key: Optional[StrictStr]
10
9
  version: Optional[StrictStr]
11
10
  dist: Optional[StrictStr]
12
11
  host: Optional[StrictStr]
13
12
  hmac: Optional[StrictStr]
13
+ mode: Optional[StrictStr]
14
+ org: Optional[bool]
14
15
  auth: Optional[List[StrictStr]]
@@ -3,6 +3,7 @@ import datetime
3
3
  from typing import Any, Dict, List, Optional, Union
4
4
 
5
5
  from clipped.compact.pydantic import StrictStr
6
+ from clipped.config.schema import BaseAllowSchemaModel
6
7
  from clipped.utils.dates import parse_datetime
7
8
  from clipped.utils.enums import PEnum
8
9
  from clipped.utils.tz import now
@@ -275,8 +276,8 @@ class LifeCycle:
275
276
  entity.started_at = now()
276
277
  # Update wait_time
277
278
  if entity.wait_time is None:
278
- entity.wait_time = int(
279
- (entity.started_at - entity.created_at).total_seconds()
279
+ entity.wait_time = round(
280
+ (entity.started_at - entity.created_at).total_seconds(), 2
280
281
  )
281
282
  return True
282
283
 
@@ -290,14 +291,14 @@ class LifeCycle:
290
291
  entity.started_at = entity.created_at
291
292
  # Update duration
292
293
  if entity.duration is None:
293
- entity.duration = int(
294
- (entity.finished_at - entity.started_at).total_seconds()
294
+ entity.duration = round(
295
+ (entity.finished_at - entity.started_at).total_seconds(), 2
295
296
  )
296
297
  return True
297
298
  return False
298
299
 
299
300
 
300
- class BaseCondition(BaseSchemaModel):
301
+ class BaseCondition(BaseAllowSchemaModel):
301
302
  @classmethod
302
303
  def get_condition(
303
304
  cls,
@@ -307,6 +308,7 @@ class BaseCondition(BaseSchemaModel):
307
308
  last_transition_time=None,
308
309
  reason=None,
309
310
  message=None,
311
+ meta_info=None,
310
312
  ):
311
313
  current_time = now()
312
314
  last_update_time = last_update_time or current_time
@@ -318,6 +320,7 @@ class BaseCondition(BaseSchemaModel):
318
320
  last_transition_time=last_transition_time,
319
321
  reason=reason,
320
322
  message=message,
323
+ meta_info=meta_info,
321
324
  )
322
325
 
323
326
  def __eq__(self, other):
@@ -335,6 +338,7 @@ class V1StatusCondition(BaseCondition):
335
338
  message: Optional[StrictStr]
336
339
  last_update_time: Optional[datetime.datetime]
337
340
  last_transition_time: Optional[datetime.datetime]
341
+ meta_info: Optional[Dict[str, Any]]
338
342
 
339
343
 
340
344
  class V1Status(BaseSchemaModel):
@@ -351,6 +355,7 @@ class V1StageCondition(BaseCondition):
351
355
  message: Optional[StrictStr]
352
356
  last_update_time: Optional[datetime.datetime]
353
357
  last_transition_time: Optional[datetime.datetime]
358
+ meta_info: Optional[Dict[str, Any]]
354
359
 
355
360
 
356
361
  class V1Stage(BaseSchemaModel):
@@ -3,11 +3,10 @@ import base64
3
3
  from typing import Optional
4
4
 
5
5
  from clipped.compact.pydantic import StrictStr
6
+ from clipped.config.schema import BaseAllowSchemaModel
6
7
 
7
- from polyaxon._schemas.base import BaseSchemaModel
8
8
 
9
-
10
- class V1LogHandler(BaseSchemaModel):
9
+ class V1LogHandler(BaseAllowSchemaModel):
11
10
  _IDENTIFIER = "log_handler"
12
11
 
13
12
  dsn: Optional[StrictStr]
@@ -129,8 +129,8 @@ class V1ArtifactsType(BaseTypeConfig):
129
129
 
130
130
  ```python
131
131
  >>> from polyaxon.schemas import V1Component, V1Init, V1Job
132
- >>> from polyaxon.schemas.types import V1ArtifactsType
133
- >>> from polyaxon.k8s import k8s_schemas
132
+ >>> from polyaxon.types import V1ArtifactsType
133
+ >>> from polyaxon import k8s
134
134
  >>> component = V1Component(
135
135
  >>> run=V1Job(
136
136
  >>> init=[
@@ -146,7 +146,7 @@ class V1ArtifactsType(BaseTypeConfig):
146
146
  >>> connection="s3-dataset"
147
147
  >>> ),
148
148
  >>> ],
149
- >>> container=k8s_schemas.V1Container(...)
149
+ >>> container=k8s.V1Container(...)
150
150
  >>> )
151
151
  >>> )
152
152
  ```
@@ -111,8 +111,8 @@ class V1DockerfileType(BaseTypeConfig):
111
111
 
112
112
  ```python
113
113
  >>> from polyaxon.schemas import V1Component, V1Init, V1Job
114
- >>> from polyaxon.schemas.types import V1DockerfileType
115
- >>> from polyaxon.k8s import k8s_schemas
114
+ >>> from polyaxon.types import V1DockerfileType
115
+ >>> from polyaxon import k8s
116
116
  >>> component = V1Component(
117
117
  >>> run=V1Job(
118
118
  >>> init=[
@@ -124,7 +124,7 @@ class V1DockerfileType(BaseTypeConfig):
124
124
  >>> )
125
125
  >>> ),
126
126
  >>> ],
127
- >>> container=k8s_schemas.V1Container(...)
127
+ >>> container=k8s.V1Container(...)
128
128
  >>> )
129
129
  >>> )
130
130
  ```
@@ -116,8 +116,8 @@ class V1FileType(BaseTypeConfig):
116
116
 
117
117
  ```python
118
118
  >>> from polyaxon.schemas import V1Component, V1Init, V1Job
119
- >>> from polyaxon.schemas.types import V1FileType
120
- >>> from polyaxon.k8s import k8s_schemas
119
+ >>> from polyaxon.types import V1FileType
120
+ >>> from polyaxon import k8s
121
121
  >>> component = V1Component(
122
122
  >>> run=V1Job(
123
123
  >>> init=[
@@ -129,7 +129,7 @@ class V1FileType(BaseTypeConfig):
129
129
  >>> )
130
130
  >>> ),
131
131
  >>> ],
132
- >>> container=k8s_schemas.V1Container(...)
132
+ >>> container=k8s.V1Container(...)
133
133
  >>> )
134
134
  >>> )
135
135
  ```
@@ -103,8 +103,8 @@ class V1GitType(BaseTypeConfig):
103
103
  ### Usage in initializers
104
104
  ```python
105
105
  >>> from polyaxon.schemas import V1Component, V1Init, V1Job
106
- >>> from polyaxon.schemas.types import V1GitType
107
- >>> from polyaxon.k8s import k8s_schemas
106
+ >>> from polyaxon.types import V1GitType
107
+ >>> from polyaxon import k8s
108
108
  >>> component = V1Component(
109
109
  >>> run=V1Job(
110
110
  >>> init=[
@@ -116,7 +116,7 @@ class V1GitType(BaseTypeConfig):
116
116
  >>> connection="my-git-connection",
117
117
  >>> ),
118
118
  >>> ],
119
- >>> container=k8s_schemas.V1Container(...)
119
+ >>> container=k8s.V1Container(...)
120
120
  >>> )
121
121
  >>> )
122
122
  ```
@@ -99,8 +99,8 @@ class V1TensorboardType(BaseTypeConfig):
99
99
 
100
100
  ```python
101
101
  >>> from polyaxon.schemas import V1Component, V1Init, V1Job
102
- >>> from polyaxon.schemas.types import V1FileType
103
- >>> from polyaxon.k8s import k8s_schemas
102
+ >>> from polyaxon.types import V1FileType
103
+ >>> from polyaxon import k8s
104
104
  >>> component = V1Component(
105
105
  >>> run=V1Job(
106
106
  >>> init=[
@@ -114,7 +114,7 @@ class V1TensorboardType(BaseTypeConfig):
114
114
  >>> )
115
115
  >>> ),
116
116
  >>> ],
117
- >>> container=k8s_schemas.V1Container(...)
117
+ >>> container=k8s.V1Container(...)
118
118
  >>> )
119
119
  >>> )
120
120
  ```