polyaxon 2.4.0rc1__py3-none-any.whl → 2.6.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.
Files changed (218) hide show
  1. polyaxon/_auxiliaries/default_scheduling.py +17 -7
  2. polyaxon/_auxiliaries/init.py +14 -6
  3. polyaxon/_auxiliaries/sidecar.py +10 -8
  4. polyaxon/_cli/dashboard.py +2 -5
  5. polyaxon/_cli/run.py +14 -0
  6. polyaxon/_cli/version.py +4 -1
  7. polyaxon/_compiler/contexts/contexts.py +4 -0
  8. polyaxon/_compiler/resolver/agent.py +10 -9
  9. polyaxon/_compiler/resolver/runtime.py +4 -0
  10. polyaxon/_constants/metadata.py +1 -0
  11. polyaxon/_contexts/keys.py +1 -0
  12. polyaxon/_deploy/schemas/auth.py +3 -3
  13. polyaxon/_deploy/schemas/celery.py +10 -8
  14. polyaxon/_deploy/schemas/deployment.py +148 -116
  15. polyaxon/_deploy/schemas/email.py +8 -8
  16. polyaxon/_deploy/schemas/ingress.py +7 -7
  17. polyaxon/_deploy/schemas/intervals.py +3 -1
  18. polyaxon/_deploy/schemas/operators.py +8 -8
  19. polyaxon/_deploy/schemas/proxy.py +9 -9
  20. polyaxon/_deploy/schemas/rbac.py +1 -1
  21. polyaxon/_deploy/schemas/root_user.py +5 -5
  22. polyaxon/_deploy/schemas/security_context.py +25 -15
  23. polyaxon/_deploy/schemas/service.py +73 -69
  24. polyaxon/_deploy/schemas/ssl.py +3 -3
  25. polyaxon/_deploy/schemas/ui.py +10 -6
  26. polyaxon/_docker/builder/builder.py +4 -1
  27. polyaxon/_docker/converter/base/containers.py +4 -7
  28. polyaxon/_docker/converter/base/env_vars.py +5 -5
  29. polyaxon/_docker/converter/base/mounts.py +2 -2
  30. polyaxon/_docker/docker_types.py +57 -30
  31. polyaxon/_env_vars/keys.py +2 -0
  32. polyaxon/_flow/__init__.py +3 -2
  33. polyaxon/_flow/builds/__init__.py +8 -8
  34. polyaxon/_flow/cache/__init__.py +4 -4
  35. polyaxon/_flow/component/base.py +25 -18
  36. polyaxon/_flow/component/component.py +4 -3
  37. polyaxon/_flow/early_stopping/__init__.py +1 -1
  38. polyaxon/_flow/early_stopping/policies.py +12 -10
  39. polyaxon/_flow/environment/__init__.py +42 -24
  40. polyaxon/_flow/events/__init__.py +1 -1
  41. polyaxon/_flow/hooks/__init__.py +11 -11
  42. polyaxon/_flow/init/__init__.py +41 -25
  43. polyaxon/_flow/io/io.py +57 -47
  44. polyaxon/_flow/joins/__init__.py +5 -5
  45. polyaxon/_flow/matrix/bayes.py +23 -17
  46. polyaxon/_flow/matrix/grid_search.py +16 -7
  47. polyaxon/_flow/matrix/hyperband.py +10 -10
  48. polyaxon/_flow/matrix/hyperopt.py +14 -9
  49. polyaxon/_flow/matrix/iterative.py +14 -8
  50. polyaxon/_flow/matrix/mapping.py +4 -4
  51. polyaxon/_flow/matrix/params.py +138 -77
  52. polyaxon/_flow/matrix/random_search.py +10 -5
  53. polyaxon/_flow/matrix/tuner.py +4 -4
  54. polyaxon/_flow/mounts/artifacts_mounts.py +1 -1
  55. polyaxon/_flow/notifications/__init__.py +1 -1
  56. polyaxon/_flow/operations/base.py +10 -8
  57. polyaxon/_flow/operations/compiled_operation.py +5 -4
  58. polyaxon/_flow/operations/operation.py +30 -22
  59. polyaxon/_flow/optimization/__init__.py +2 -2
  60. polyaxon/_flow/params/params.py +10 -9
  61. polyaxon/_flow/plugins/__init__.py +19 -13
  62. polyaxon/_flow/run/dag.py +12 -9
  63. polyaxon/_flow/run/dask/dask.py +4 -4
  64. polyaxon/_flow/run/dask/replica.py +17 -11
  65. polyaxon/_flow/run/job.py +17 -11
  66. polyaxon/_flow/run/kubeflow/mpi_job.py +10 -5
  67. polyaxon/_flow/run/kubeflow/mx_job.py +25 -9
  68. polyaxon/_flow/run/kubeflow/paddle_job.py +16 -9
  69. polyaxon/_flow/run/kubeflow/pytorch_job.py +24 -17
  70. polyaxon/_flow/run/kubeflow/replica.py +17 -11
  71. polyaxon/_flow/run/kubeflow/scheduling_policy.py +7 -5
  72. polyaxon/_flow/run/kubeflow/tf_job.py +15 -8
  73. polyaxon/_flow/run/kubeflow/xgboost_job.py +9 -4
  74. polyaxon/_flow/run/ray/ray.py +9 -6
  75. polyaxon/_flow/run/ray/replica.py +25 -16
  76. polyaxon/_flow/run/resources.py +14 -13
  77. polyaxon/_flow/run/service.py +4 -4
  78. polyaxon/_flow/schedules/cron.py +4 -4
  79. polyaxon/_flow/schedules/interval.py +4 -4
  80. polyaxon/_flow/templates/__init__.py +3 -3
  81. polyaxon/_flow/termination/__init__.py +3 -3
  82. polyaxon/_fs/async_manager.py +1 -1
  83. polyaxon/_fs/watcher.py +26 -27
  84. polyaxon/_k8s/k8s_validation.py +1 -1
  85. polyaxon/_k8s/logging/async_monitor.py +18 -3
  86. polyaxon/_local_process/converter/base/containers.py +4 -7
  87. polyaxon/_local_process/converter/base/env_vars.py +5 -5
  88. polyaxon/_local_process/process_types.py +15 -12
  89. polyaxon/_polyaxonfile/specs/compiled_operation.py +1 -1
  90. polyaxon/_polyaxonfile/specs/libs/parser.py +1 -1
  91. polyaxon/_polyaxonfile/specs/libs/validator.py +1 -1
  92. polyaxon/_polyaxonfile/specs/operation.py +1 -1
  93. polyaxon/_polyaxonfile/specs/sections.py +8 -0
  94. polyaxon/_runner/agent/async_agent.py +9 -6
  95. polyaxon/_runner/agent/base_agent.py +8 -5
  96. polyaxon/_runner/agent/sync_agent.py +8 -5
  97. polyaxon/_runner/converter/converter.py +12 -4
  98. polyaxon/_schemas/agent.py +69 -37
  99. polyaxon/_schemas/authentication.py +4 -4
  100. polyaxon/_schemas/base.py +26 -2
  101. polyaxon/_schemas/checks.py +3 -3
  102. polyaxon/_schemas/cli.py +4 -6
  103. polyaxon/_schemas/client.py +20 -18
  104. polyaxon/_schemas/compatibility.py +4 -4
  105. polyaxon/_schemas/container_resources.py +1 -1
  106. polyaxon/_schemas/home.py +3 -3
  107. polyaxon/_schemas/installation.py +13 -9
  108. polyaxon/_schemas/lifecycle.py +23 -23
  109. polyaxon/_schemas/log_handler.py +2 -2
  110. polyaxon/_schemas/services.py +26 -14
  111. polyaxon/_schemas/types/artifacts.py +3 -3
  112. polyaxon/_schemas/types/dockerfile.py +14 -12
  113. polyaxon/_schemas/types/event.py +2 -2
  114. polyaxon/_schemas/types/file.py +3 -3
  115. polyaxon/_schemas/types/git.py +12 -4
  116. polyaxon/_schemas/types/tensorboard.py +14 -8
  117. polyaxon/_schemas/user.py +3 -3
  118. polyaxon/_schemas/version.py +2 -2
  119. polyaxon/_sdk/api/agents_v1_api.py +45 -45
  120. polyaxon/_sdk/api/artifacts_stores_v1_api.py +3 -3
  121. polyaxon/_sdk/api/auth_v1_api.py +13 -13
  122. polyaxon/_sdk/api/connections_v1_api.py +15 -15
  123. polyaxon/_sdk/api/dashboards_v1_api.py +15 -15
  124. polyaxon/_sdk/api/organizations_v1_api.py +77 -77
  125. polyaxon/_sdk/api/presets_v1_api.py +15 -15
  126. polyaxon/_sdk/api/project_dashboards_v1_api.py +17 -17
  127. polyaxon/_sdk/api/project_searches_v1_api.py +17 -17
  128. polyaxon/_sdk/api/projects_v1_api.py +65 -65
  129. polyaxon/_sdk/api/queues_v1_api.py +19 -19
  130. polyaxon/_sdk/api/runs_v1_api.py +127 -127
  131. polyaxon/_sdk/api/searches_v1_api.py +15 -15
  132. polyaxon/_sdk/api/service_accounts_v1_api.py +27 -27
  133. polyaxon/_sdk/api/tags_v1_api.py +17 -17
  134. polyaxon/_sdk/api/teams_v1_api.py +51 -51
  135. polyaxon/_sdk/api/users_v1_api.py +25 -25
  136. polyaxon/_sdk/api/versions_v1_api.py +7 -7
  137. polyaxon/_sdk/schemas/v1_activity.py +8 -8
  138. polyaxon/_sdk/schemas/v1_agent.py +17 -16
  139. polyaxon/_sdk/schemas/v1_agent_state_response.py +4 -4
  140. polyaxon/_sdk/schemas/v1_agent_state_response_agent_state.py +10 -10
  141. polyaxon/_sdk/schemas/v1_agent_status_body_request.py +3 -3
  142. polyaxon/_sdk/schemas/v1_analytics_spec.py +4 -4
  143. polyaxon/_sdk/schemas/v1_artifact_tree.py +3 -3
  144. polyaxon/_sdk/schemas/v1_auth.py +1 -1
  145. polyaxon/_sdk/schemas/v1_cloning.py +3 -3
  146. polyaxon/_sdk/schemas/v1_connection_response.py +9 -9
  147. polyaxon/_sdk/schemas/v1_dashboard.py +9 -9
  148. polyaxon/_sdk/schemas/v1_dashboard_spec.py +5 -5
  149. polyaxon/_sdk/schemas/v1_entities_tags.py +2 -2
  150. polyaxon/_sdk/schemas/v1_entities_transfer.py +2 -2
  151. polyaxon/_sdk/schemas/v1_entity_notification_body.py +7 -7
  152. polyaxon/_sdk/schemas/v1_entity_stage_body_request.py +5 -5
  153. polyaxon/_sdk/schemas/v1_entity_status_body_request.py +5 -5
  154. polyaxon/_sdk/schemas/v1_events_response.py +2 -2
  155. polyaxon/_sdk/schemas/v1_list_activities_response.py +4 -4
  156. polyaxon/_sdk/schemas/v1_list_agents_response.py +4 -4
  157. polyaxon/_sdk/schemas/v1_list_bookmarks_response.py +4 -4
  158. polyaxon/_sdk/schemas/v1_list_connections_response.py +4 -4
  159. polyaxon/_sdk/schemas/v1_list_dashboards_response.py +4 -4
  160. polyaxon/_sdk/schemas/v1_list_organization_members_response.py +4 -4
  161. polyaxon/_sdk/schemas/v1_list_organizations_response.py +4 -4
  162. polyaxon/_sdk/schemas/v1_list_presets_response.py +4 -4
  163. polyaxon/_sdk/schemas/v1_list_project_versions_response.py +4 -4
  164. polyaxon/_sdk/schemas/v1_list_projects_response.py +4 -4
  165. polyaxon/_sdk/schemas/v1_list_queues_response.py +4 -4
  166. polyaxon/_sdk/schemas/v1_list_run_artifacts_response.py +4 -4
  167. polyaxon/_sdk/schemas/v1_list_run_connections_response.py +4 -4
  168. polyaxon/_sdk/schemas/v1_list_run_edges_response.py +4 -4
  169. polyaxon/_sdk/schemas/v1_list_runs_response.py +4 -4
  170. polyaxon/_sdk/schemas/v1_list_searches_response.py +4 -4
  171. polyaxon/_sdk/schemas/v1_list_service_accounts_response.py +4 -4
  172. polyaxon/_sdk/schemas/v1_list_tags_response.py +4 -4
  173. polyaxon/_sdk/schemas/v1_list_team_members_response.py +4 -4
  174. polyaxon/_sdk/schemas/v1_list_teams_response.py +4 -4
  175. polyaxon/_sdk/schemas/v1_list_token_response.py +4 -4
  176. polyaxon/_sdk/schemas/v1_operation_body.py +8 -8
  177. polyaxon/_sdk/schemas/v1_organization.py +16 -16
  178. polyaxon/_sdk/schemas/v1_organization_member.py +6 -6
  179. polyaxon/_sdk/schemas/v1_password_change.py +3 -3
  180. polyaxon/_sdk/schemas/v1_pipeline.py +3 -3
  181. polyaxon/_sdk/schemas/v1_preset.py +11 -12
  182. polyaxon/_sdk/schemas/v1_project.py +17 -17
  183. polyaxon/_sdk/schemas/v1_project_settings.py +11 -11
  184. polyaxon/_sdk/schemas/v1_project_version.py +20 -20
  185. polyaxon/_sdk/schemas/v1_queue.py +12 -12
  186. polyaxon/_sdk/schemas/v1_run.py +38 -38
  187. polyaxon/_sdk/schemas/v1_run_connection.py +3 -3
  188. polyaxon/_sdk/schemas/v1_run_edge.py +5 -5
  189. polyaxon/_sdk/schemas/v1_run_edge_lineage.py +3 -3
  190. polyaxon/_sdk/schemas/v1_run_edges_graph.py +1 -1
  191. polyaxon/_sdk/schemas/v1_run_reference_catalog.py +4 -4
  192. polyaxon/_sdk/schemas/v1_run_settings.py +9 -9
  193. polyaxon/_sdk/schemas/v1_search.py +10 -10
  194. polyaxon/_sdk/schemas/v1_search_spec.py +14 -14
  195. polyaxon/_sdk/schemas/v1_section_spec.py +12 -12
  196. polyaxon/_sdk/schemas/v1_service_account.py +9 -9
  197. polyaxon/_sdk/schemas/v1_settings_catalog.py +4 -4
  198. polyaxon/_sdk/schemas/v1_tag.py +6 -6
  199. polyaxon/_sdk/schemas/v1_team.py +11 -11
  200. polyaxon/_sdk/schemas/v1_team_member.py +6 -6
  201. polyaxon/_sdk/schemas/v1_team_settings.py +2 -2
  202. polyaxon/_sdk/schemas/v1_token.py +10 -10
  203. polyaxon/_sdk/schemas/v1_trial_start.py +6 -6
  204. polyaxon/_sdk/schemas/v1_user.py +6 -6
  205. polyaxon/_sdk/schemas/v1_user_access.py +7 -7
  206. polyaxon/_sdk/schemas/v1_user_email.py +1 -1
  207. polyaxon/_sdk/schemas/v1_user_singup.py +5 -5
  208. polyaxon/_sdk/schemas/v1_uuids.py +1 -1
  209. polyaxon/_sidecar/container/__init__.py +13 -8
  210. polyaxon/_utils/cli_constants.py +2 -0
  211. polyaxon/_utils/test_utils.py +2 -1
  212. polyaxon/pkg.py +1 -1
  213. {polyaxon-2.4.0rc1.dist-info → polyaxon-2.6.0.dist-info}/METADATA +13 -13
  214. {polyaxon-2.4.0rc1.dist-info → polyaxon-2.6.0.dist-info}/RECORD +218 -218
  215. {polyaxon-2.4.0rc1.dist-info → polyaxon-2.6.0.dist-info}/WHEEL +1 -1
  216. {polyaxon-2.4.0rc1.dist-info → polyaxon-2.6.0.dist-info}/LICENSE +0 -0
  217. {polyaxon-2.4.0rc1.dist-info → polyaxon-2.6.0.dist-info}/entry_points.txt +0 -0
  218. {polyaxon-2.4.0rc1.dist-info → polyaxon-2.6.0.dist-info}/top_level.txt +0 -0
@@ -45,7 +45,7 @@ class BaseSyncAgent(BaseAgent):
45
45
  self.client.log_agent_failed(message="{} {}".format(message, reason))
46
46
  raise PolyaxonAgentError(message="{} {}".format(message, reason))
47
47
  except Exception as e:
48
- raise PolyaxonAgentError from e
48
+ raise PolyaxonAgentError(f"Unexpected error: {str(e)}") from e
49
49
 
50
50
  def _exit(self):
51
51
  if not self.client._is_managed:
@@ -79,14 +79,17 @@ class BaseSyncAgent(BaseAgent):
79
79
 
80
80
  def reconcile(self):
81
81
  if (
82
- now() - self._last_reconciled_at
82
+ now() - self._last_data_collected_at
83
83
  ).total_seconds() > self.SLEEP_AGENT_DATA_COLLECT_TIME:
84
+ self.collect_agent_data()
85
+ if (
86
+ now() - self._last_reconciled_at
87
+ ).total_seconds() < self.SLEEP_AGENT_DATA_RECONCILE_TIME:
84
88
  return
85
89
 
86
- # Collect data
87
- self.collect_agent_data()
88
-
89
90
  # Update reconcile
91
+ logger.info("Checking cluster state.")
92
+ self._last_reconciled_at = now()
90
93
  namespaces = [settings.AGENT_CONFIG.namespace]
91
94
  namespaces += settings.AGENT_CONFIG.additional_namespaces or []
92
95
  ops = []
@@ -820,7 +820,7 @@ class BaseConverter:
820
820
  connection=V1Connection(
821
821
  name=git_name,
822
822
  kind=V1ConnectionKind.GIT,
823
- schema_=init_connection.git,
823
+ schema_=init_connection.git.to_connection(),
824
824
  secret=None,
825
825
  ),
826
826
  container=self._ensure_container(
@@ -930,15 +930,23 @@ class BaseConverter:
930
930
 
931
931
  # Add outputs
932
932
  if plugins and plugins.collect_artifacts:
933
+ _artifacts_init_env = []
934
+ if log_level:
935
+ _artifacts_init_env.append(
936
+ self._get_env_var(name=ENV_KEYS_LOG_LEVEL, value=log_level)
937
+ )
938
+ proxy_env = self._get_proxy_env_vars(
939
+ settings.AGENT_CONFIG.use_proxy_env_vars_use_in_ops
940
+ )
941
+ if proxy_env:
942
+ _artifacts_init_env += proxy_env
933
943
  containers += to_list(
934
944
  self._get_artifacts_path_init_container(
935
945
  polyaxon_init=polyaxon_init,
936
946
  artifacts_store=artifacts_store,
937
947
  run_path=self.run_path,
938
948
  auto_resume=plugins.auto_resume,
939
- env=self._get_proxy_env_vars(
940
- settings.AGENT_CONFIG.use_proxy_env_vars_use_in_ops
941
- ),
949
+ env=_artifacts_init_env,
942
950
  ),
943
951
  check_none=True,
944
952
  )
@@ -2,7 +2,13 @@ import os
2
2
 
3
3
  from typing import Dict, List, Optional
4
4
 
5
- from clipped.compact.pydantic import Extra, Field, StrictStr, root_validator, validator
5
+ from clipped.compact.pydantic import (
6
+ Field,
7
+ StrictStr,
8
+ field_validator,
9
+ model_validator,
10
+ validation_before,
11
+ )
6
12
  from clipped.config.schema import skip_partial, to_partial
7
13
  from vents.connections import ConnectionCatalog
8
14
 
@@ -70,16 +76,18 @@ def validate_agent_config(
70
76
  class BaseAgentConfig(ConnectionCatalog, BaseSchemaModel):
71
77
  _REQUIRED_ARTIFACTS_STORE = True
72
78
 
73
- connections: Optional[List[V1Connection]] = Field(alias=ENV_KEYS_AGENT_CONNECTIONS)
79
+ connections: Optional[List[V1Connection]] = Field(
80
+ default=None, alias=ENV_KEYS_AGENT_CONNECTIONS
81
+ )
74
82
  artifacts_store: Optional[V1Connection] = Field(
75
- alias=ENV_KEYS_AGENT_ARTIFACTS_STORE
83
+ default=None, alias=ENV_KEYS_AGENT_ARTIFACTS_STORE
76
84
  )
77
- namespace: Optional[StrictStr] = Field(alias=ENV_KEYS_K8S_NAMESPACE)
85
+ namespace: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_K8S_NAMESPACE)
78
86
 
79
87
  class Config:
80
- extra = Extra.ignore
88
+ extra = "ignore"
81
89
 
82
- @root_validator(pre=True)
90
+ @model_validator(**validation_before)
83
91
  def handle_camel_case_artifacts_store(cls, values):
84
92
  if (
85
93
  not values.get("artifacts_store")
@@ -89,7 +97,7 @@ class BaseAgentConfig(ConnectionCatalog, BaseSchemaModel):
89
97
  values[ENV_KEYS_AGENT_ARTIFACTS_STORE] = values["artifactsStore"]
90
98
  return values
91
99
 
92
- @validator("connections", pre=True)
100
+ @field_validator("connections", **validation_before)
93
101
  def validate_json_list(cls, v):
94
102
  if not isinstance(v, str):
95
103
  return v
@@ -103,7 +111,7 @@ class BaseAgentConfig(ConnectionCatalog, BaseSchemaModel):
103
111
  except PolyaxonSchemaError as e:
104
112
  raise ValueError("Received an invalid connections") from e
105
113
 
106
- @validator("artifacts_store", pre=True)
114
+ @field_validator("artifacts_store", **validation_before)
107
115
  def validate_store_json(cls, v):
108
116
  if not isinstance(v, str):
109
117
  return v
@@ -118,9 +126,10 @@ class BaseAgentConfig(ConnectionCatalog, BaseSchemaModel):
118
126
  "Received an invalid artifacts store `{}`".format(v)
119
127
  ) from e
120
128
 
121
- @validator("artifacts_store")
129
+ @field_validator("artifacts_store")
122
130
  @skip_partial
123
131
  def validate_agent_config(cls, artifacts_store, values):
132
+ values = cls.get_data_from_values(values)
124
133
  try:
125
134
  validate_agent_config(
126
135
  artifacts_store,
@@ -186,38 +195,59 @@ class BaseAgentConfig(ConnectionCatalog, BaseSchemaModel):
186
195
 
187
196
  class AgentConfig(BaseAgentConfig):
188
197
  _IDENTIFIER = "agent"
198
+ _CUSTOM_DUMP_FIELDS = {
199
+ "sidecar",
200
+ "init",
201
+ "notifier",
202
+ "cleaner",
203
+ "default_scheduling",
204
+ }
189
205
 
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)
206
+ is_replica: Optional[bool] = Field(default=None, alias=ENV_KEYS_AGENT_IS_REPLICA)
207
+ watch_cluster: Optional[bool] = Field(default=None, alias=ENV_KEYS_WATCH_CLUSTER)
208
+ single_namespace: Optional[bool] = Field(
209
+ default=None, alias=ENV_KEYS_SINGLE_NAMESPACE
210
+ )
193
211
  additional_namespaces: Optional[List[StrictStr]] = Field(
194
- alias=ENV_KEYS_ADDITIONAL_NAMESPACES
212
+ default=None, alias=ENV_KEYS_ADDITIONAL_NAMESPACES
213
+ )
214
+ sidecar: Optional[V1PolyaxonSidecarContainer] = Field(
215
+ default=None, alias=ENV_KEYS_AGENT_SIDECAR
216
+ )
217
+ init: Optional[V1PolyaxonInitContainer] = Field(
218
+ default=None, alias=ENV_KEYS_AGENT_INIT
219
+ )
220
+ notifier: Optional[V1PolyaxonNotifier] = Field(
221
+ default=None, alias=ENV_KEYS_AGENT_NOTIFIER
222
+ )
223
+ cleaner: Optional[V1PolyaxonCleaner] = Field(
224
+ default=None, alias=ENV_KEYS_AGENT_CLEANER
195
225
  )
196
- sidecar: Optional[V1PolyaxonSidecarContainer] = Field(alias=ENV_KEYS_AGENT_SIDECAR)
197
- init: Optional[V1PolyaxonInitContainer] = Field(alias=ENV_KEYS_AGENT_INIT)
198
- notifier: Optional[V1PolyaxonNotifier] = Field(alias=ENV_KEYS_AGENT_NOTIFIER)
199
- cleaner: Optional[V1PolyaxonCleaner] = Field(alias=ENV_KEYS_AGENT_CLEANER)
200
226
  use_proxy_env_vars_use_in_ops: Optional[bool] = Field(
201
- alias=ENV_KEYS_AGENT_USE_PROXY_ENV_VARS_IN_OPS
227
+ default=None, alias=ENV_KEYS_AGENT_USE_PROXY_ENV_VARS_IN_OPS
202
228
  )
203
229
  default_scheduling: Optional[V1DefaultScheduling] = Field(
204
- alias=ENV_KEYS_AGENT_DEFAULT_SCHEDULING
230
+ default=None, alias=ENV_KEYS_AGENT_DEFAULT_SCHEDULING
205
231
  )
206
232
  default_image_pull_secrets: Optional[List[StrictStr]] = Field(
207
- alias=ENV_KEYS_AGENT_DEFAULT_IMAGE_PULL_SECRETS
233
+ default=None, alias=ENV_KEYS_AGENT_DEFAULT_IMAGE_PULL_SECRETS
234
+ )
235
+ app_secret_name: Optional[StrictStr] = Field(
236
+ default=None, alias=ENV_KEYS_K8S_APP_SECRET_NAME
208
237
  )
209
- app_secret_name: Optional[StrictStr] = Field(alias=ENV_KEYS_K8S_APP_SECRET_NAME)
210
- agent_secret_name: Optional[StrictStr] = Field(alias=ENV_KEYS_AGENT_SECRET_NAME)
211
- runs_sa: Optional[StrictStr] = Field(alias=ENV_KEYS_AGENT_RUNS_SA)
238
+ agent_secret_name: Optional[StrictStr] = Field(
239
+ default=None, alias=ENV_KEYS_AGENT_SECRET_NAME
240
+ )
241
+ runs_sa: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_AGENT_RUNS_SA)
212
242
  enable_health_checks: Optional[bool] = Field(
213
- alias=ENV_KEYS_AGENT_ENABLE_HEALTH_CHECKS
243
+ default=None, alias=ENV_KEYS_AGENT_ENABLE_HEALTH_CHECKS
214
244
  )
215
245
  # This refresh logic will mitigate several issues with AKS's numerous networking problems
216
246
  executor_refresh_interval: Optional[int] = Field(
217
- alias=ENV_KEYS_AGENT_EXECUTOR_REFRESH_INTERVAL
247
+ default=None, alias=ENV_KEYS_AGENT_EXECUTOR_REFRESH_INTERVAL
218
248
  )
219
249
 
220
- @root_validator(pre=True)
250
+ @model_validator(**validation_before)
221
251
  def handle_camel_case_agent(cls, values):
222
252
  if (
223
253
  not values.get("is_replica")
@@ -307,6 +337,8 @@ class AgentConfig(BaseAgentConfig):
307
337
  ):
308
338
  if not default_scheduling and default_image_pull_secrets:
309
339
  default_scheduling = V1DefaultScheduling()
340
+ if default_scheduling and isinstance(default_scheduling, dict):
341
+ default_scheduling = V1DefaultScheduling.from_dict(default_scheduling)
310
342
  if default_scheduling and not default_scheduling.image_pull_secrets:
311
343
  default_scheduling.image_pull_secrets = default_image_pull_secrets
312
344
  super().__init__(
@@ -315,42 +347,42 @@ class AgentConfig(BaseAgentConfig):
315
347
  **data,
316
348
  )
317
349
 
318
- @validator(
350
+ @field_validator(
319
351
  "artifacts_store",
320
352
  "sidecar",
321
353
  "init",
322
354
  "cleaner",
323
355
  "notifier",
324
356
  "default_scheduling",
325
- pre=True,
357
+ **validation_before,
326
358
  )
327
359
  def validate_json(cls, v, field):
328
360
  if not isinstance(v, str):
329
361
  return v
362
+ key = cls.get_alias_for_field(field)
330
363
  try:
331
364
  return ConfigParser.parse(Dict)(
332
- key=field.name,
365
+ key=key,
333
366
  value=v,
334
367
  is_optional=True,
335
368
  )
336
369
  except PolyaxonSchemaError as e:
337
- raise ValueError(
338
- "Received an invalid {} `{}`".format(field.alias, v)
339
- ) from e
370
+ raise ValueError("Received an invalid {} `{}`".format(key, v)) from e
340
371
 
341
- @validator("additional_namespaces", "default_image_pull_secrets", pre=True)
372
+ @field_validator(
373
+ "additional_namespaces", "default_image_pull_secrets", **validation_before
374
+ )
342
375
  def validate_str_list(cls, v, field):
376
+ key = cls.get_alias_for_field(field)
343
377
  try:
344
378
  return ConfigParser.parse(str)(
345
- key=field.alias,
379
+ key=key,
346
380
  value=v,
347
381
  is_optional=True,
348
382
  is_list=True,
349
383
  )
350
384
  except PolyaxonSchemaError as e:
351
- raise ValueError(
352
- "Received an invalid {} `{}`".format(field.alias, v)
353
- ) from e
385
+ raise ValueError("Received an invalid {} `{}`".format(key, v)) from e
354
386
 
355
387
  def get_executor_refresh_interval(self) -> int:
356
388
  return self.executor_refresh_interval or 60 * 5
@@ -1,6 +1,6 @@
1
1
  from typing import Optional
2
2
 
3
- from clipped.compact.pydantic import Extra, Field, StrictStr
3
+ from clipped.compact.pydantic import Field, StrictStr
4
4
 
5
5
  from polyaxon._env_vars.keys import ENV_KEYS_AUTH_TOKEN, ENV_KEYS_AUTH_USERNAME
6
6
  from polyaxon._schemas.base import BaseSchemaModel
@@ -18,11 +18,11 @@ class AccessTokenConfig(BaseSchemaModel):
18
18
 
19
19
  _IDENTIFIER = "token"
20
20
 
21
- username: Optional[StrictStr] = Field(alias=ENV_KEYS_AUTH_USERNAME)
22
- token: Optional[StrictStr] = Field(alias=ENV_KEYS_AUTH_TOKEN)
21
+ username: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_AUTH_USERNAME)
22
+ token: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_AUTH_TOKEN)
23
23
 
24
24
  class Config:
25
- extra = Extra.ignore
25
+ extra = "ignore"
26
26
 
27
27
 
28
28
  class V1Credentials(BaseSchemaModel):
polyaxon/_schemas/base.py CHANGED
@@ -1,4 +1,6 @@
1
+ from clipped.compact.pydantic import PYDANTIC_VERSION
1
2
  from clipped.config.schema import BaseSchemaModel as _BaseSchemaModel
3
+ from clipped.config.schema import RootModel as _RootModel
2
4
 
3
5
  from polyaxon import pkg
4
6
  from polyaxon._config.spec import ConfigSpec
@@ -11,5 +13,27 @@ class BaseSchemaModel(_BaseSchemaModel):
11
13
  _CONFIG_SPEC = ConfigSpec
12
14
 
13
15
 
14
- NAME_REGEX = r"^[-a-zA-Z0-9_]+\Z"
15
- FULLY_QUALIFIED_NAME_REGEX = r"^[-a-zA-Z0-9_]+(:[-a-zA-Z0-9_.]+)?\Z"
16
+ class RootModel(_RootModel):
17
+ _VERSION = pkg.SCHEMA_VERSION
18
+ _SCHEMA_EXCEPTION = PolyaxonSchemaError
19
+ _CONFIG_SPEC = ConfigSpec
20
+
21
+ @property
22
+ def _root(self):
23
+ return self.__root__ if hasattr(self, "__root__") else self.root
24
+
25
+ def set_root(self, value):
26
+ if hasattr(self, "__root__"):
27
+ self.__root__ = value
28
+ else:
29
+ self.root = value
30
+ return self
31
+
32
+ def get_root(self):
33
+ return self._root
34
+
35
+ @classmethod
36
+ def make(cls, value):
37
+ if PYDANTIC_VERSION.startswith("2."):
38
+ return cls(root=value)
39
+ return cls(__root__=value)
@@ -1,7 +1,7 @@
1
1
  import os
2
2
 
3
3
  from datetime import datetime, timedelta
4
- from typing import Optional
4
+ from typing import ClassVar, Optional
5
5
 
6
6
  from clipped.utils.tz import now
7
7
 
@@ -11,9 +11,9 @@ from polyaxon._schemas.base import BaseSchemaModel
11
11
 
12
12
  class ChecksConfig(BaseSchemaModel):
13
13
  _IDENTIFIER = "checks"
14
- _INTERVAL = 30 * 60
14
+ _INTERVAL: ClassVar[int] = 30 * 60
15
15
 
16
- last_check: Optional[datetime]
16
+ last_check: Optional[datetime] = None
17
17
 
18
18
  def __init__(
19
19
  self,
polyaxon/_schemas/cli.py CHANGED
@@ -11,13 +11,11 @@ from polyaxon._schemas.log_handler import V1LogHandler
11
11
 
12
12
  class CliConfig(ChecksConfig):
13
13
  _IDENTIFIER = "cli"
14
- _DIST = "dist"
15
- _INTERVAL = 30 * 60
16
14
 
17
- current_version: Optional[StrictStr]
18
- installation: Optional[V1Installation]
19
- compatibility: Optional[V1Compatibility]
20
- log_handler: Optional[V1LogHandler]
15
+ current_version: Optional[StrictStr] = None
16
+ installation: Optional[V1Installation] = None
17
+ compatibility: Optional[V1Compatibility] = None
18
+ log_handler: Optional[V1LogHandler] = None
21
19
 
22
20
  @property
23
21
  def min_version(self) -> Optional[str]:
@@ -4,7 +4,7 @@ from typing import Dict, Optional, Union
4
4
 
5
5
  import urllib3
6
6
 
7
- from clipped.compact.pydantic import Extra, Field, StrictStr
7
+ from clipped.compact.pydantic import Field, StrictStr
8
8
  from clipped.utils.http import clean_host
9
9
 
10
10
  from polyaxon._contexts import paths as ctx_paths
@@ -55,10 +55,10 @@ class ClientConfig(BaseSchemaModel):
55
55
  _PAGE_SIZE = 20
56
56
  _BASE_URL = "{}/api/{}"
57
57
 
58
- host: Optional[StrictStr] = Field(alias=ENV_KEYS_HOST)
58
+ host: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_HOST)
59
59
  version: Optional[StrictStr] = Field(default="v1", alias=ENV_KEYS_API_VERSION)
60
60
  debug: Optional[bool] = Field(default=False, alias=ENV_KEYS_DEBUG)
61
- log_level: Optional[StrictStr] = Field(alias=ENV_KEYS_LOG_LEVEL)
61
+ log_level: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_LOG_LEVEL)
62
62
  authentication_type: Optional[StrictStr] = Field(
63
63
  default=AuthenticationTypes.TOKEN, alias=ENV_KEYS_AUTHENTICATION_TYPE
64
64
  )
@@ -70,40 +70,42 @@ class ClientConfig(BaseSchemaModel):
70
70
  tracking_timeout: Optional[float] = Field(
71
71
  default=1, alias=ENV_KEYS_TRACKING_TIMEOUT
72
72
  )
73
- timezone: Optional[StrictStr] = Field(alias=ENV_KEYS_TIME_ZONE)
73
+ timezone: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_TIME_ZONE)
74
74
  watch_interval: Optional[int] = Field(default=5, alias=ENV_KEYS_WATCH_INTERVAL)
75
75
  interval: Optional[float] = Field(default=5, alias=ENV_KEYS_INTERVAL)
76
- verify_ssl: Optional[bool] = Field(alias=ENV_KEYS_VERIFY_SSL)
77
- ssl_ca_cert: Optional[StrictStr] = Field(alias=ENV_KEYS_SSL_CA_CERT)
78
- cert_file: Optional[StrictStr] = Field(alias=ENV_KEYS_CERT_FILE)
79
- key_file: Optional[StrictStr] = Field(alias=ENV_KEYS_KEY_FILE)
80
- assert_hostname: Optional[bool] = Field(alias=ENV_KEYS_ASSERT_HOSTNAME)
76
+ verify_ssl: Optional[bool] = Field(default=None, alias=ENV_KEYS_VERIFY_SSL)
77
+ ssl_ca_cert: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_SSL_CA_CERT)
78
+ cert_file: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_CERT_FILE)
79
+ key_file: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_KEY_FILE)
80
+ assert_hostname: Optional[bool] = Field(
81
+ default=None, alias=ENV_KEYS_ASSERT_HOSTNAME
82
+ )
81
83
  connection_pool_maxsize: Optional[int] = Field(
82
- alias=ENV_KEYS_CONNECTION_POOL_MAXSIZE
84
+ default=None, alias=ENV_KEYS_CONNECTION_POOL_MAXSIZE
83
85
  )
84
86
  archives_root: Optional[StrictStr] = Field(
85
87
  default=ctx_paths.CONTEXT_ARCHIVES_ROOT, alias=ENV_KEYS_ARCHIVES_ROOT
86
88
  )
87
89
  header: Optional[Union[StrictStr, PolyaxonServiceHeaders]] = Field(
88
- alias=ENV_KEYS_HEADER
90
+ default=None, alias=ENV_KEYS_HEADER
89
91
  )
90
92
  header_service: Optional[Union[StrictStr, PolyaxonServices]] = Field(
91
- alias=ENV_KEYS_HEADER_SERVICE
93
+ default=None, alias=ENV_KEYS_HEADER_SERVICE
92
94
  )
93
- namespace: Optional[StrictStr] = Field(alias=ENV_KEYS_K8S_NAMESPACE)
95
+ namespace: Optional[StrictStr] = Field(default=None, alias=ENV_KEYS_K8S_NAMESPACE)
94
96
  no_api: Optional[bool] = Field(default=False, alias=ENV_KEYS_NO_API)
95
97
  disable_errors_reporting: Optional[bool] = Field(
96
98
  default=False, alias=ENV_KEYS_DISABLE_ERRORS_REPORTING
97
99
  )
98
100
  compatibility_check_interval: Optional[int] = Field(
99
- alias=ENV_KEYS_INTERVALS_COMPATIBILITY_CHECK
101
+ default=None, alias=ENV_KEYS_INTERVALS_COMPATIBILITY_CHECK
100
102
  )
101
- retries: Optional[int] = Field(alias=ENV_KEYS_RETRIES)
102
- token: Optional[StrictStr]
103
- client_header: Optional[Dict]
103
+ retries: Optional[int] = Field(default=None, alias=ENV_KEYS_RETRIES)
104
+ token: Optional[StrictStr] = None
105
+ client_header: Optional[Dict] = None
104
106
 
105
107
  class Config:
106
- extra = Extra.ignore
108
+ extra = "ignore"
107
109
 
108
110
  def __init__(
109
111
  self,
@@ -5,7 +5,7 @@ from polyaxon._schemas.version import V1Version
5
5
 
6
6
 
7
7
  class V1Compatibility(BaseSchemaModel):
8
- cli: Optional[V1Version]
9
- platform: Optional[V1Version]
10
- agent: Optional[V1Version]
11
- ui: Optional[V1Version]
8
+ cli: Optional[V1Version] = None
9
+ platform: Optional[V1Version] = None
10
+ agent: Optional[V1Version] = None
11
+ ui: Optional[V1Version] = None
@@ -25,7 +25,7 @@ class ContainerGPUResourcesConfig(BaseSchemaModel):
25
25
  memory_used: StrictIntOrFloat
26
26
  memory_total: StrictIntOrFloat
27
27
  memory_utilization: StrictIntOrFloat
28
- processes: Optional[List[Dict]]
28
+ processes: Optional[List[Dict]] = None
29
29
 
30
30
 
31
31
  class ContainerResourcesConfig(BaseSchemaModel):
polyaxon/_schemas/home.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from typing import Optional
2
2
 
3
- from clipped.compact.pydantic import Extra, Field, StrictStr
3
+ from clipped.compact.pydantic import Field, StrictStr
4
4
 
5
5
  from polyaxon._env_vars.keys import ENV_KEYS_HOME
6
6
  from polyaxon._schemas.base import BaseSchemaModel
@@ -17,7 +17,7 @@ class HomeConfig(BaseSchemaModel):
17
17
 
18
18
  _IDENTIFIER = "home"
19
19
 
20
- path: Optional[StrictStr] = Field(alias=ENV_KEYS_HOME)
20
+ path: Optional[StrictStr] = Field(alias=ENV_KEYS_HOME, default=None)
21
21
 
22
22
  class Config:
23
- extra = Extra.ignore
23
+ extra = "ignore"
@@ -1,15 +1,19 @@
1
1
  from typing import List, Optional
2
2
 
3
- from clipped.compact.pydantic import StrictStr
3
+ from clipped.compact.pydantic import Field, StrictStr
4
4
  from clipped.config.schema import BaseAllowSchemaModel
5
5
 
6
6
 
7
7
  class V1Installation(BaseAllowSchemaModel):
8
- key: Optional[StrictStr]
9
- version: Optional[StrictStr]
10
- dist: Optional[StrictStr]
11
- host: Optional[StrictStr]
12
- hmac: Optional[StrictStr]
13
- mode: Optional[StrictStr]
14
- org: Optional[bool]
15
- auth: Optional[List[StrictStr]]
8
+ key: Optional[StrictStr] = None
9
+ version: Optional[StrictStr] = None
10
+ dist: Optional[StrictStr] = None
11
+ host: Optional[StrictStr] = None
12
+ hmac: Optional[StrictStr] = None
13
+ mode: Optional[StrictStr] = None
14
+ org: Optional[bool] = None
15
+ auth: Optional[List[StrictStr]] = None
16
+ single_url: Optional[bool] = Field(alias="singleUrl", default=None)
17
+ default_streams_url: Optional[StrictStr] = Field(
18
+ alias="defaultStreamsUrl", default=None
19
+ )
@@ -185,7 +185,7 @@ class LifeCycle:
185
185
 
186
186
  @classmethod
187
187
  def is_pending(cls, status: str) -> bool:
188
- """Checks if a run with this status is in a pending status."""
188
+ """Checks if a run with this status is in one of the pending(not compiled or queued yet) statuses."""
189
189
  return status in cls.PENDING_VALUES
190
190
 
191
191
  @classmethod
@@ -220,7 +220,7 @@ class LifeCycle:
220
220
 
221
221
  @classmethod
222
222
  def is_safe_stoppable(cls, status: str) -> bool:
223
- """Checks if a run with this status is an be stopped without operator."""
223
+ """Checks if a run with this status is can be stopped without calling the operator."""
224
224
  return status in cls.SAFE_STOP_VALUES
225
225
 
226
226
  @classmethod
@@ -332,36 +332,36 @@ class BaseCondition(BaseAllowSchemaModel):
332
332
 
333
333
 
334
334
  class V1StatusCondition(BaseCondition):
335
- type: Optional[V1Statuses]
336
- status: Optional[Union[bool, str]]
337
- reason: Optional[StrictStr]
338
- message: Optional[StrictStr]
339
- last_update_time: Optional[datetime.datetime]
340
- last_transition_time: Optional[datetime.datetime]
341
- meta_info: Optional[Dict[str, Any]]
335
+ type: Optional[V1Statuses] = None
336
+ status: Optional[Union[bool, str]] = None
337
+ reason: Optional[StrictStr] = None
338
+ message: Optional[StrictStr] = None
339
+ last_update_time: Optional[datetime.datetime] = None
340
+ last_transition_time: Optional[datetime.datetime] = None
341
+ meta_info: Optional[Dict[str, Any]] = None
342
342
 
343
343
 
344
344
  class V1Status(BaseSchemaModel):
345
- uuid: Optional[StrictStr]
346
- status: Optional[V1Statuses]
347
- status_conditions: Optional[List[V1StatusCondition]]
348
- meta_info: Optional[Dict[str, Any]]
345
+ uuid: Optional[StrictStr] = None
346
+ status: Optional[V1Statuses] = None
347
+ status_conditions: Optional[List[V1StatusCondition]] = None
348
+ meta_info: Optional[Dict[str, Any]] = None
349
349
 
350
350
 
351
351
  class V1StageCondition(BaseCondition):
352
- type: Optional[V1Stages]
353
- status: Optional[Union[bool, str]]
354
- reason: Optional[StrictStr]
355
- message: Optional[StrictStr]
356
- last_update_time: Optional[datetime.datetime]
357
- last_transition_time: Optional[datetime.datetime]
358
- meta_info: Optional[Dict[str, Any]]
352
+ type: Optional[V1Stages] = None
353
+ status: Optional[Union[bool, str]] = None
354
+ reason: Optional[StrictStr] = None
355
+ message: Optional[StrictStr] = None
356
+ last_update_time: Optional[datetime.datetime] = None
357
+ last_transition_time: Optional[datetime.datetime] = None
358
+ meta_info: Optional[Dict[str, Any]] = None
359
359
 
360
360
 
361
361
  class V1Stage(BaseSchemaModel):
362
- uuid: Optional[StrictStr]
363
- stage: Optional[V1Stages]
364
- stage_conditions: Optional[List[V1StageCondition]]
362
+ uuid: Optional[StrictStr] = None
363
+ stage: Optional[V1Stages] = None
364
+ stage_conditions: Optional[List[V1StageCondition]] = None
365
365
 
366
366
 
367
367
  class V1ProjectVersionKind(str, PEnum):
@@ -9,8 +9,8 @@ from clipped.config.schema import BaseAllowSchemaModel
9
9
  class V1LogHandler(BaseAllowSchemaModel):
10
10
  _IDENTIFIER = "log_handler"
11
11
 
12
- dsn: Optional[StrictStr]
13
- environment: Optional[StrictStr]
12
+ dsn: Optional[StrictStr] = None
13
+ environment: Optional[StrictStr] = None
14
14
 
15
15
  @property
16
16
  def decoded_dsn(self):