feat(api): Replace PodTemplateOverrides with RuntimePatches API (#3309)

* feat(api): Replace PodTemplateOverrides with RuntimePatches API

Signed-off-by: Andrey Velichkevich <[email protected]>

* Update goal with RuntimePatches API

Signed-off-by: Andrey Velichkevich <[email protected]>

* Add diagram for RuntimePatches

Signed-off-by: Andrey Velichkevich <[email protected]>

* feat(api): Replace PodTemplateOverrides with RuntimePatches API

Signed-off-by: Antonin Stefanutti <[email protected]>

* Fix kube lint errors

Signed-off-by: Antonin Stefanutti <[email protected]>

* Update Python models

Signed-off-by: Antonin Stefanutti <[email protected]>

* Enable maxlength Kube-API-Linter rule

Signed-off-by: Antonin Stefanutti <[email protected]>

* Restore manger field IsDomainPrefixedPath validation

Signed-off-by: Antonin Stefanutti <[email protected]>

* Fix integration tests

Signed-off-by: Antonin Stefanutti <[email protected]>

* Apply StrategicMergePatch to batchv1.JobTemplateSpec

Signed-off-by: Antonin Stefanutti <[email protected]>

---------

Signed-off-by: Andrey Velichkevich <[email protected]>
Signed-off-by: Antonin Stefanutti <[email protected]>
Co-authored-by: Andrey Velichkevich <[email protected]>
This commit is contained in:
Antonin Stefanutti
2026-03-12 16:29:44 +00:00
committed by GitHub
co-authored by Andrey Velichkevich
parent f105c84c58
commit 37c8a07a8a
52 changed files with 14122 additions and 9852 deletions
+10 -4
View File
@@ -358,22 +358,27 @@ from kubeflow_trainer_api.models.jobset_v1alpha2_volume_retention_policy import
from kubeflow_trainer_api.models.scheduling_v1beta1_network_topology_spec import SchedulingV1beta1NetworkTopologySpec
from kubeflow_trainer_api.models.trainer_v1alpha1_cluster_training_runtime import TrainerV1alpha1ClusterTrainingRuntime
from kubeflow_trainer_api.models.trainer_v1alpha1_cluster_training_runtime_list import TrainerV1alpha1ClusterTrainingRuntimeList
from kubeflow_trainer_api.models.trainer_v1alpha1_container_override import TrainerV1alpha1ContainerOverride
from kubeflow_trainer_api.models.trainer_v1alpha1_container_patch import TrainerV1alpha1ContainerPatch
from kubeflow_trainer_api.models.trainer_v1alpha1_coscheduling_pod_group_policy_source import TrainerV1alpha1CoschedulingPodGroupPolicySource
from kubeflow_trainer_api.models.trainer_v1alpha1_dataset_initializer import TrainerV1alpha1DatasetInitializer
from kubeflow_trainer_api.models.trainer_v1alpha1_flux_ml_policy_source import TrainerV1alpha1FluxMLPolicySource
from kubeflow_trainer_api.models.trainer_v1alpha1_initializer import TrainerV1alpha1Initializer
from kubeflow_trainer_api.models.trainer_v1alpha1_job_set_spec_patch import TrainerV1alpha1JobSetSpecPatch
from kubeflow_trainer_api.models.trainer_v1alpha1_job_set_template_patch import TrainerV1alpha1JobSetTemplatePatch
from kubeflow_trainer_api.models.trainer_v1alpha1_job_set_template_spec import TrainerV1alpha1JobSetTemplateSpec
from kubeflow_trainer_api.models.trainer_v1alpha1_job_spec_patch import TrainerV1alpha1JobSpecPatch
from kubeflow_trainer_api.models.trainer_v1alpha1_job_status import TrainerV1alpha1JobStatus
from kubeflow_trainer_api.models.trainer_v1alpha1_job_template_patch import TrainerV1alpha1JobTemplatePatch
from kubeflow_trainer_api.models.trainer_v1alpha1_ml_policy import TrainerV1alpha1MLPolicy
from kubeflow_trainer_api.models.trainer_v1alpha1_ml_policy_source import TrainerV1alpha1MLPolicySource
from kubeflow_trainer_api.models.trainer_v1alpha1_mpiml_policy_source import TrainerV1alpha1MPIMLPolicySource
from kubeflow_trainer_api.models.trainer_v1alpha1_model_initializer import TrainerV1alpha1ModelInitializer
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_group_policy import TrainerV1alpha1PodGroupPolicy
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_group_policy_source import TrainerV1alpha1PodGroupPolicySource
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_template_override import TrainerV1alpha1PodTemplateOverride
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_template_override_target_job import TrainerV1alpha1PodTemplateOverrideTargetJob
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_template_spec_override import TrainerV1alpha1PodTemplateSpecOverride
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_spec_patch import TrainerV1alpha1PodSpecPatch
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_template_patch import TrainerV1alpha1PodTemplatePatch
from kubeflow_trainer_api.models.trainer_v1alpha1_replicated_job_patch import TrainerV1alpha1ReplicatedJobPatch
from kubeflow_trainer_api.models.trainer_v1alpha1_runtime_patch import TrainerV1alpha1RuntimePatch
from kubeflow_trainer_api.models.trainer_v1alpha1_runtime_ref import TrainerV1alpha1RuntimeRef
from kubeflow_trainer_api.models.trainer_v1alpha1_train_job import TrainerV1alpha1TrainJob
from kubeflow_trainer_api.models.trainer_v1alpha1_train_job_list import TrainerV1alpha1TrainJobList
@@ -383,4 +388,5 @@ from kubeflow_trainer_api.models.trainer_v1alpha1_trainer import TrainerV1alpha1
from kubeflow_trainer_api.models.trainer_v1alpha1_training_runtime import TrainerV1alpha1TrainingRuntime
from kubeflow_trainer_api.models.trainer_v1alpha1_training_runtime_list import TrainerV1alpha1TrainingRuntimeList
from kubeflow_trainer_api.models.trainer_v1alpha1_training_runtime_spec import TrainerV1alpha1TrainingRuntimeSpec
from kubeflow_trainer_api.models.trainer_v1alpha1_training_runtime_spec_patch import TrainerV1alpha1TrainingRuntimeSpecPatch
from kubeflow_trainer_api.models.trainer_v1alpha1_volcano_pod_group_policy_source import TrainerV1alpha1VolcanoPodGroupPolicySource
@@ -0,0 +1,113 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.io_k8s_api_core_v1_env_var import IoK8sApiCoreV1EnvVar
from kubeflow_trainer_api.models.io_k8s_api_core_v1_security_context import IoK8sApiCoreV1SecurityContext
from kubeflow_trainer_api.models.io_k8s_api_core_v1_volume_mount import IoK8sApiCoreV1VolumeMount
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1ContainerPatch(BaseModel):
"""
ContainerPatch represents parameters that can be patched using PodSpecPatch.
""" # noqa: E501
env: Optional[List[IoK8sApiCoreV1EnvVar]] = Field(default=None, description="env is the list of environment variables to set in the container. These values will be merged with the Runtime's environments. These values can't be set for container with the name: `node`, `dataset-initializer`, or `model-initializer`. For those containers the envs can only be set via Trainer or Initializer APIs.")
name: StrictStr = Field(description="name for the container. Runtime must have this container.")
security_context: Optional[IoK8sApiCoreV1SecurityContext] = Field(default=None, description="securityContext patches the container's security context. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", alias="securityContext")
volume_mounts: Optional[List[IoK8sApiCoreV1VolumeMount]] = Field(default=None, description="volumeMounts are the volumes to mount into the container's filesystem.", alias="volumeMounts")
__properties: ClassVar[List[str]] = ["env", "name", "securityContext", "volumeMounts"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1ContainerPatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of each item in env (list)
_items = []
if self.env:
for _item_env in self.env:
if _item_env:
_items.append(_item_env.to_dict())
_dict['env'] = _items
# override the default output from pydantic by calling `to_dict()` of security_context
if self.security_context:
_dict['securityContext'] = self.security_context.to_dict()
# override the default output from pydantic by calling `to_dict()` of each item in volume_mounts (list)
_items = []
if self.volume_mounts:
for _item_volume_mounts in self.volume_mounts:
if _item_volume_mounts:
_items.append(_item_volume_mounts.to_dict())
_dict['volumeMounts'] = _items
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1ContainerPatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"env": [IoK8sApiCoreV1EnvVar.from_dict(_item) for _item in obj["env"]] if obj.get("env") is not None else None,
"name": obj.get("name"),
"securityContext": IoK8sApiCoreV1SecurityContext.from_dict(obj["securityContext"]) if obj.get("securityContext") is not None else None,
"volumeMounts": [IoK8sApiCoreV1VolumeMount.from_dict(_item) for _item in obj["volumeMounts"]] if obj.get("volumeMounts") is not None else None
})
return _obj
@@ -0,0 +1,95 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.trainer_v1alpha1_replicated_job_patch import TrainerV1alpha1ReplicatedJobPatch
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1JobSetSpecPatch(BaseModel):
"""
JobSetSpecPatch defines allowed patches for the JobSet spec.
""" # noqa: E501
replicated_jobs: Optional[List[TrainerV1alpha1ReplicatedJobPatch]] = Field(default=None, description="replicatedJobs defines per-job patches, keyed by job name.", alias="replicatedJobs")
__properties: ClassVar[List[str]] = ["replicatedJobs"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1JobSetSpecPatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of each item in replicated_jobs (list)
_items = []
if self.replicated_jobs:
for _item_replicated_jobs in self.replicated_jobs:
if _item_replicated_jobs:
_items.append(_item_replicated_jobs.to_dict())
_dict['replicatedJobs'] = _items
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1JobSetSpecPatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"replicatedJobs": [TrainerV1alpha1ReplicatedJobPatch.from_dict(_item) for _item in obj["replicatedJobs"]] if obj.get("replicatedJobs") is not None else None
})
return _obj
@@ -0,0 +1,97 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.io_k8s_apimachinery_pkg_apis_meta_v1_object_meta import IoK8sApimachineryPkgApisMetaV1ObjectMeta
from kubeflow_trainer_api.models.trainer_v1alpha1_job_set_spec_patch import TrainerV1alpha1JobSetSpecPatch
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1JobSetTemplatePatch(BaseModel):
"""
JobSetTemplatePatch defines patches for the JobSet template. It mirrors JobSetTemplateSpec but only exposes metadata and restricted spec fields.
""" # noqa: E501
metadata: Optional[IoK8sApimachineryPkgApisMetaV1ObjectMeta] = Field(default=None, description="metadata patches the JobSet object metadata. Only labels and annotations are allowed.")
spec: Optional[TrainerV1alpha1JobSetSpecPatch] = Field(default=None, description="spec patches the JobSet spec with restricted fields.")
__properties: ClassVar[List[str]] = ["metadata", "spec"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1JobSetTemplatePatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of metadata
if self.metadata:
_dict['metadata'] = self.metadata.to_dict()
# override the default output from pydantic by calling `to_dict()` of spec
if self.spec:
_dict['spec'] = self.spec.to_dict()
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1JobSetTemplatePatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"metadata": IoK8sApimachineryPkgApisMetaV1ObjectMeta.from_dict(obj["metadata"]) if obj.get("metadata") is not None else None,
"spec": TrainerV1alpha1JobSetSpecPatch.from_dict(obj["spec"]) if obj.get("spec") is not None else None
})
return _obj
@@ -0,0 +1,91 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_template_patch import TrainerV1alpha1PodTemplatePatch
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1JobSpecPatch(BaseModel):
"""
JobSpecPatch defines allowed patches for the Job spec.
""" # noqa: E501
template: Optional[TrainerV1alpha1PodTemplatePatch] = Field(default=None, description="template patches the Pod template for this Job.")
__properties: ClassVar[List[str]] = ["template"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1JobSpecPatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of template
if self.template:
_dict['template'] = self.template.to_dict()
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1JobSpecPatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"template": TrainerV1alpha1PodTemplatePatch.from_dict(obj["template"]) if obj.get("template") is not None else None
})
return _obj
@@ -0,0 +1,97 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.io_k8s_apimachinery_pkg_apis_meta_v1_object_meta import IoK8sApimachineryPkgApisMetaV1ObjectMeta
from kubeflow_trainer_api.models.trainer_v1alpha1_job_spec_patch import TrainerV1alpha1JobSpecPatch
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1JobTemplatePatch(BaseModel):
"""
JobTemplatePatch defines patches for a Job template within a replicated job.
""" # noqa: E501
metadata: Optional[IoK8sApimachineryPkgApisMetaV1ObjectMeta] = Field(default=None, description="metadata patches the Job template metadata. Only labels and annotations are allowed.")
spec: Optional[TrainerV1alpha1JobSpecPatch] = Field(default=None, description="spec patches the Job spec with restricted fields.")
__properties: ClassVar[List[str]] = ["metadata", "spec"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1JobTemplatePatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of metadata
if self.metadata:
_dict['metadata'] = self.metadata.to_dict()
# override the default output from pydantic by calling `to_dict()` of spec
if self.spec:
_dict['spec'] = self.spec.to_dict()
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1JobTemplatePatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"metadata": IoK8sApimachineryPkgApisMetaV1ObjectMeta.from_dict(obj["metadata"]) if obj.get("metadata") is not None else None,
"spec": TrainerV1alpha1JobSpecPatch.from_dict(obj["spec"]) if obj.get("spec") is not None else None
})
return _obj
@@ -0,0 +1,160 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.io_k8s_api_core_v1_affinity import IoK8sApiCoreV1Affinity
from kubeflow_trainer_api.models.io_k8s_api_core_v1_local_object_reference import IoK8sApiCoreV1LocalObjectReference
from kubeflow_trainer_api.models.io_k8s_api_core_v1_pod_scheduling_gate import IoK8sApiCoreV1PodSchedulingGate
from kubeflow_trainer_api.models.io_k8s_api_core_v1_pod_security_context import IoK8sApiCoreV1PodSecurityContext
from kubeflow_trainer_api.models.io_k8s_api_core_v1_toleration import IoK8sApiCoreV1Toleration
from kubeflow_trainer_api.models.io_k8s_api_core_v1_volume import IoK8sApiCoreV1Volume
from kubeflow_trainer_api.models.trainer_v1alpha1_container_patch import TrainerV1alpha1ContainerPatch
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1PodSpecPatch(BaseModel):
"""
PodSpecPatch contains the Pod spec fields that managers are permitted to patch.
""" # noqa: E501
affinity: Optional[IoK8sApiCoreV1Affinity] = Field(default=None, description="affinity patches the Pod's scheduling affinity.")
containers: Optional[List[TrainerV1alpha1ContainerPatch]] = Field(default=None, description="containers patches specific containers in the target job templates.")
image_pull_secrets: Optional[List[IoK8sApiCoreV1LocalObjectReference]] = Field(default=None, description="imagePullSecrets patches the image pull secrets for the Pods in the target job templates.", alias="imagePullSecrets")
init_containers: Optional[List[TrainerV1alpha1ContainerPatch]] = Field(default=None, description="initContainers patches the init containers in the target job templates.", alias="initContainers")
node_selector: Optional[Dict[str, StrictStr]] = Field(default=None, description="nodeSelector patches the node selector to place Pods on specific nodes.", alias="nodeSelector")
scheduling_gates: Optional[List[IoK8sApiCoreV1PodSchedulingGate]] = Field(default=None, description="schedulingGates patches the scheduling gates for the Pods in the target job templates. More info: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-scheduling-readiness/", alias="schedulingGates")
security_context: Optional[IoK8sApiCoreV1PodSecurityContext] = Field(default=None, description="securityContext patches the Pod's security context. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", alias="securityContext")
service_account_name: Optional[StrictStr] = Field(default=None, description="serviceAccountName patches the service account for the Pods in the target job templates.", alias="serviceAccountName")
tolerations: Optional[List[IoK8sApiCoreV1Toleration]] = Field(default=None, description="tolerations patches the Pod's tolerations.")
volumes: Optional[List[IoK8sApiCoreV1Volume]] = Field(default=None, description="volumes patches the Pod's volumes.")
__properties: ClassVar[List[str]] = ["affinity", "containers", "imagePullSecrets", "initContainers", "nodeSelector", "schedulingGates", "securityContext", "serviceAccountName", "tolerations", "volumes"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1PodSpecPatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of affinity
if self.affinity:
_dict['affinity'] = self.affinity.to_dict()
# override the default output from pydantic by calling `to_dict()` of each item in containers (list)
_items = []
if self.containers:
for _item_containers in self.containers:
if _item_containers:
_items.append(_item_containers.to_dict())
_dict['containers'] = _items
# override the default output from pydantic by calling `to_dict()` of each item in image_pull_secrets (list)
_items = []
if self.image_pull_secrets:
for _item_image_pull_secrets in self.image_pull_secrets:
if _item_image_pull_secrets:
_items.append(_item_image_pull_secrets.to_dict())
_dict['imagePullSecrets'] = _items
# override the default output from pydantic by calling `to_dict()` of each item in init_containers (list)
_items = []
if self.init_containers:
for _item_init_containers in self.init_containers:
if _item_init_containers:
_items.append(_item_init_containers.to_dict())
_dict['initContainers'] = _items
# override the default output from pydantic by calling `to_dict()` of each item in scheduling_gates (list)
_items = []
if self.scheduling_gates:
for _item_scheduling_gates in self.scheduling_gates:
if _item_scheduling_gates:
_items.append(_item_scheduling_gates.to_dict())
_dict['schedulingGates'] = _items
# override the default output from pydantic by calling `to_dict()` of security_context
if self.security_context:
_dict['securityContext'] = self.security_context.to_dict()
# override the default output from pydantic by calling `to_dict()` of each item in tolerations (list)
_items = []
if self.tolerations:
for _item_tolerations in self.tolerations:
if _item_tolerations:
_items.append(_item_tolerations.to_dict())
_dict['tolerations'] = _items
# override the default output from pydantic by calling `to_dict()` of each item in volumes (list)
_items = []
if self.volumes:
for _item_volumes in self.volumes:
if _item_volumes:
_items.append(_item_volumes.to_dict())
_dict['volumes'] = _items
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1PodSpecPatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"affinity": IoK8sApiCoreV1Affinity.from_dict(obj["affinity"]) if obj.get("affinity") is not None else None,
"containers": [TrainerV1alpha1ContainerPatch.from_dict(_item) for _item in obj["containers"]] if obj.get("containers") is not None else None,
"imagePullSecrets": [IoK8sApiCoreV1LocalObjectReference.from_dict(_item) for _item in obj["imagePullSecrets"]] if obj.get("imagePullSecrets") is not None else None,
"initContainers": [TrainerV1alpha1ContainerPatch.from_dict(_item) for _item in obj["initContainers"]] if obj.get("initContainers") is not None else None,
"nodeSelector": obj.get("nodeSelector"),
"schedulingGates": [IoK8sApiCoreV1PodSchedulingGate.from_dict(_item) for _item in obj["schedulingGates"]] if obj.get("schedulingGates") is not None else None,
"securityContext": IoK8sApiCoreV1PodSecurityContext.from_dict(obj["securityContext"]) if obj.get("securityContext") is not None else None,
"serviceAccountName": obj.get("serviceAccountName"),
"tolerations": [IoK8sApiCoreV1Toleration.from_dict(_item) for _item in obj["tolerations"]] if obj.get("tolerations") is not None else None,
"volumes": [IoK8sApiCoreV1Volume.from_dict(_item) for _item in obj["volumes"]] if obj.get("volumes") is not None else None
})
return _obj
@@ -0,0 +1,97 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.io_k8s_apimachinery_pkg_apis_meta_v1_object_meta import IoK8sApimachineryPkgApisMetaV1ObjectMeta
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_spec_patch import TrainerV1alpha1PodSpecPatch
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1PodTemplatePatch(BaseModel):
"""
PodTemplatePatch defines patches for a Pod template within a Job.
""" # noqa: E501
metadata: Optional[IoK8sApimachineryPkgApisMetaV1ObjectMeta] = Field(default=None, description="metadata patches the Pod template metadata. Only labels and annotations are allowed.")
spec: Optional[TrainerV1alpha1PodSpecPatch] = Field(default=None, description="spec patches the Pod spec with the fields managers are permitted to set.")
__properties: ClassVar[List[str]] = ["metadata", "spec"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1PodTemplatePatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of metadata
if self.metadata:
_dict['metadata'] = self.metadata.to_dict()
# override the default output from pydantic by calling `to_dict()` of spec
if self.spec:
_dict['spec'] = self.spec.to_dict()
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1PodTemplatePatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"metadata": IoK8sApimachineryPkgApisMetaV1ObjectMeta.from_dict(obj["metadata"]) if obj.get("metadata") is not None else None,
"spec": TrainerV1alpha1PodSpecPatch.from_dict(obj["spec"]) if obj.get("spec") is not None else None
})
return _obj
@@ -0,0 +1,93 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.trainer_v1alpha1_job_template_patch import TrainerV1alpha1JobTemplatePatch
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1ReplicatedJobPatch(BaseModel):
"""
ReplicatedJobPatch defines patches for a specific replicated job within the JobSet.
""" # noqa: E501
name: StrictStr = Field(description="name is the name of the replicated job to patch.")
template: Optional[TrainerV1alpha1JobTemplatePatch] = Field(default=None, description="template patches the Job template for this replicated job.")
__properties: ClassVar[List[str]] = ["name", "template"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1ReplicatedJobPatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of template
if self.template:
_dict['template'] = self.template.to_dict()
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1ReplicatedJobPatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"name": obj.get("name"),
"template": TrainerV1alpha1JobTemplatePatch.from_dict(obj["template"]) if obj.get("template") is not None else None
})
return _obj
@@ -0,0 +1,96 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.trainer_v1alpha1_training_runtime_spec_patch import TrainerV1alpha1TrainingRuntimeSpecPatch
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1RuntimePatch(BaseModel):
"""
RuntimePatch represents a custom patch applied to the TrainJob's training runtime template. Patches are keyed by manager to provide clear ownership and avoid conflicts between controllers.
""" # noqa: E501
manager: StrictStr = Field(description="manager indicates who owns this patch entry. It can be set by the user, external controllers, or admission webhooks to track ownership and avoid conflicts. For example, Kueue sets this field to \"kueue.x-k8s.io/manager\".")
time: Optional[datetime] = Field(default=None, description="time is the timestamp of when this patch was last written. Set by the Trainer admission webhook on each create or update. Used for observability only, not used as a list map key.")
training_runtime_spec: Optional[TrainerV1alpha1TrainingRuntimeSpecPatch] = Field(default=None, description="trainingRuntimeSpec defines allowed patches for ClusterTrainingRuntime or TrainingRuntime-based jobs.", alias="trainingRuntimeSpec")
__properties: ClassVar[List[str]] = ["manager", "time", "trainingRuntimeSpec"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1RuntimePatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of training_runtime_spec
if self.training_runtime_spec:
_dict['trainingRuntimeSpec'] = self.training_runtime_spec.to_dict()
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1RuntimePatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"manager": obj.get("manager"),
"time": obj.get("time"),
"trainingRuntimeSpec": TrainerV1alpha1TrainingRuntimeSpecPatch.from_dict(obj["trainingRuntimeSpec"]) if obj.get("trainingRuntimeSpec") is not None else None
})
return _obj
@@ -20,7 +20,7 @@ import json
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.trainer_v1alpha1_initializer import TrainerV1alpha1Initializer
from kubeflow_trainer_api.models.trainer_v1alpha1_pod_template_override import TrainerV1alpha1PodTemplateOverride
from kubeflow_trainer_api.models.trainer_v1alpha1_runtime_patch import TrainerV1alpha1RuntimePatch
from kubeflow_trainer_api.models.trainer_v1alpha1_runtime_ref import TrainerV1alpha1RuntimeRef
from kubeflow_trainer_api.models.trainer_v1alpha1_trainer import TrainerV1alpha1Trainer
from typing import Optional, Set
@@ -30,15 +30,13 @@ class TrainerV1alpha1TrainJobSpec(BaseModel):
"""
TrainJobSpec represents specification of the desired TrainJob.
""" # noqa: E501
annotations: Optional[Dict[str, StrictStr]] = Field(default=None, description="annotations to apply for the derivative JobSet and Jobs. They will be merged with the TrainingRuntime values.")
initializer: Optional[TrainerV1alpha1Initializer] = Field(default=None, description="initializer defines the configuration of the initializer.")
labels: Optional[Dict[str, StrictStr]] = Field(default=None, description="labels to apply for the derivative JobSet and Jobs. They will be merged with the TrainingRuntime values.")
managed_by: Optional[StrictStr] = Field(default=None, description="managedBy is used to indicate the controller or entity that manages a TrainJob. The value must be either an empty, `trainer.kubeflow.org/trainjob-controller` or `kueue.x-k8s.io/multikueue`. The built-in TrainJob controller reconciles TrainJob which don't have this field at all or the field value is the reserved string `trainer.kubeflow.org/trainjob-controller`, but delegates reconciling TrainJobs with a 'kueue.x-k8s.io/multikueue' to the Kueue. The field is immutable.", alias="managedBy")
pod_template_overrides: Optional[List[TrainerV1alpha1PodTemplateOverride]] = Field(default=None, description="podTemplateOverrides define the PodTemplateOverrides for the training runtime. When multiple overrides apply to the same targetJob, later entries in the slice override earlier field values.", alias="podTemplateOverrides")
runtime_patches: Optional[List[TrainerV1alpha1RuntimePatch]] = Field(default=None, description="runtimePatches defines custom patches applied to the TrainJob's Runtime. Patches are keyed by manager to provide clear ownership and avoid conflicts between controllers.", alias="runtimePatches")
runtime_ref: TrainerV1alpha1RuntimeRef = Field(description="runtimeRef is the reference to the training runtime.", alias="runtimeRef")
suspend: Optional[StrictBool] = Field(default=None, description="suspend defines whether to suspend the running TrainJob.")
trainer: Optional[TrainerV1alpha1Trainer] = Field(default=None, description="trainer defines the configuration of the trainer.")
__properties: ClassVar[List[str]] = ["annotations", "initializer", "labels", "managedBy", "podTemplateOverrides", "runtimeRef", "suspend", "trainer"]
__properties: ClassVar[List[str]] = ["initializer", "managedBy", "runtimePatches", "runtimeRef", "suspend", "trainer"]
model_config = ConfigDict(
populate_by_name=True,
@@ -82,13 +80,13 @@ class TrainerV1alpha1TrainJobSpec(BaseModel):
# override the default output from pydantic by calling `to_dict()` of initializer
if self.initializer:
_dict['initializer'] = self.initializer.to_dict()
# override the default output from pydantic by calling `to_dict()` of each item in pod_template_overrides (list)
# override the default output from pydantic by calling `to_dict()` of each item in runtime_patches (list)
_items = []
if self.pod_template_overrides:
for _item_pod_template_overrides in self.pod_template_overrides:
if _item_pod_template_overrides:
_items.append(_item_pod_template_overrides.to_dict())
_dict['podTemplateOverrides'] = _items
if self.runtime_patches:
for _item_runtime_patches in self.runtime_patches:
if _item_runtime_patches:
_items.append(_item_runtime_patches.to_dict())
_dict['runtimePatches'] = _items
# override the default output from pydantic by calling `to_dict()` of runtime_ref
if self.runtime_ref:
_dict['runtimeRef'] = self.runtime_ref.to_dict()
@@ -107,11 +105,9 @@ class TrainerV1alpha1TrainJobSpec(BaseModel):
return cls.model_validate(obj)
_obj = cls.model_validate({
"annotations": obj.get("annotations"),
"initializer": TrainerV1alpha1Initializer.from_dict(obj["initializer"]) if obj.get("initializer") is not None else None,
"labels": obj.get("labels"),
"managedBy": obj.get("managedBy"),
"podTemplateOverrides": [TrainerV1alpha1PodTemplateOverride.from_dict(_item) for _item in obj["podTemplateOverrides"]] if obj.get("podTemplateOverrides") is not None else None,
"runtimePatches": [TrainerV1alpha1RuntimePatch.from_dict(_item) for _item in obj["runtimePatches"]] if obj.get("runtimePatches") is not None else None,
"runtimeRef": TrainerV1alpha1RuntimeRef.from_dict(obj["runtimeRef"]) if obj.get("runtimeRef") is not None else None,
"suspend": obj.get("suspend"),
"trainer": TrainerV1alpha1Trainer.from_dict(obj["trainer"]) if obj.get("trainer") is not None else None
@@ -0,0 +1,91 @@
# coding: utf-8
"""
Kubeflow Trainer OpenAPI Spec
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
The version of the OpenAPI document: unversioned
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, Field
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_trainer_api.models.trainer_v1alpha1_job_set_template_patch import TrainerV1alpha1JobSetTemplatePatch
from typing import Optional, Set
from typing_extensions import Self
class TrainerV1alpha1TrainingRuntimeSpecPatch(BaseModel):
"""
TrainingRuntimeSpecPatch mirrors TrainingRuntimeSpec but only exposes the fields managers are permitted to patch.
""" # noqa: E501
template: Optional[TrainerV1alpha1JobSetTemplatePatch] = Field(default=None, description="template patches the JobSet template.")
__properties: ClassVar[List[str]] = ["template"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1TrainingRuntimeSpecPatch from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# override the default output from pydantic by calling `to_dict()` of template
if self.template:
_dict['template'] = self.template.to_dict()
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of TrainerV1alpha1TrainingRuntimeSpecPatch from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"template": TrainerV1alpha1JobSetTemplatePatch.from_dict(obj["template"]) if obj.get("template") is not None else None
})
return _obj