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
@@ -4,7 +4,7 @@ from datetime import datetime
4
4
  from requests import HTTPError
5
5
  from typing import Dict, List, Optional, Tuple, Union
6
6
 
7
- from clipped.utils.json import orjson_dumps
7
+ from clipped.utils.json import orjson_dumps, orjson_loads
8
8
  from clipped.utils.paths import check_or_create_path, delete_path
9
9
  from clipped.utils.query_params import get_query_params
10
10
  from clipped.utils.tz import now
@@ -12,6 +12,7 @@ from clipped.utils.validation import validate_tags
12
12
 
13
13
  from polyaxon._client.client import PolyaxonClient
14
14
  from polyaxon._client.decorators import client_handler, get_global_or_inline_config
15
+ from polyaxon._client.mixin import ClientMixin
15
16
  from polyaxon._constants.globals import DEFAULT
16
17
  from polyaxon._contexts import paths as ctx_paths
17
18
  from polyaxon._env_vars.getters.user import get_local_owner
@@ -21,13 +22,17 @@ from polyaxon._sdk.schemas.v1_list_project_versions_response import (
21
22
  )
22
23
  from polyaxon._sdk.schemas.v1_project import V1Project
23
24
  from polyaxon._sdk.schemas.v1_project_version import V1ProjectVersion
24
- from polyaxon._utils.fqn_utils import get_entity_full_name, get_entity_info
25
+ from polyaxon._utils.fqn_utils import (
26
+ get_entity_full_name,
27
+ get_entity_info,
28
+ split_owner_team_space,
29
+ )
25
30
  from polyaxon.exceptions import ApiException, PolyaxonClientException
26
31
  from polyaxon.logger import logger
27
32
  from traceml.artifacts import V1RunArtifact
28
33
 
29
34
 
30
- class ProjectClient:
35
+ class ProjectClient(ClientMixin):
31
36
  """ProjectClient is a client to communicate with Polyaxon projects endpoints.
32
37
 
33
38
  If no values are passed to this class,
@@ -94,26 +99,13 @@ class ProjectClient:
94
99
  if not owner:
95
100
  raise PolyaxonClientException("Please provide a valid owner.")
96
101
 
102
+ owner, team = split_owner_team_space(owner)
97
103
  self._client = client
98
104
  self._owner = owner or DEFAULT
105
+ self._team = team
99
106
  self._project = project
100
107
  self._project_data = V1Project.construct()
101
108
 
102
- @property
103
- def client(self):
104
- if self._client:
105
- return self._client
106
- self._client = PolyaxonClient()
107
- return self._client
108
-
109
- @property
110
- def owner(self):
111
- return self._owner
112
-
113
- @property
114
- def project(self):
115
- return self._project
116
-
117
109
  @property
118
110
  def project_data(self):
119
111
  return self._project_data
@@ -139,11 +131,19 @@ class ProjectClient:
139
131
  Returns:
140
132
  V1Project, project instance from the response.
141
133
  """
142
- self._project_data = self.client.projects_v1.create_project(
143
- self.owner,
144
- data,
145
- async_req=False,
146
- )
134
+ if self.team:
135
+ self._project_data = self.client.projects_v1.create_team_project(
136
+ self.owner,
137
+ self.team,
138
+ data,
139
+ async_req=False,
140
+ )
141
+ else:
142
+ self._project_data = self.client.projects_v1.create_project(
143
+ self.owner,
144
+ data,
145
+ async_req=False,
146
+ )
147
147
  self._project_data.owner = self.owner
148
148
  self._project = self._project_data.name
149
149
  return self._project_data
@@ -727,9 +727,12 @@ class ProjectClient:
727
727
  description: Optional[str] = None,
728
728
  tags: Optional[Union[str, List[str]]] = None,
729
729
  content: Optional[Union[str, Dict]] = None,
730
+ readme: Optional[str] = None,
730
731
  run: Optional[str] = None,
731
732
  connection: Optional[str] = None,
732
733
  artifacts: Optional[List[str]] = None,
734
+ stage: Optional[V1Stages] = None,
735
+ stage_conditions: Optional[List[V1StageCondition]] = None,
733
736
  force: bool = False,
734
737
  ) -> V1ProjectVersion:
735
738
  """Creates or Updates a project version based on the data passed.
@@ -745,9 +748,12 @@ class ProjectClient:
745
748
  description: str, optional, the version description.
746
749
  tags: str or List[str], optional.
747
750
  content: str or dict, optional, content/metadata (JSON object) of the version.
751
+ readme: str, optional, the version readme.
748
752
  run: str, optional, a uuid reference to the run.
749
753
  connection: str, optional, a uuid reference to a connection.
750
754
  artifacts: List[str], optional, list of artifacts to highlight(requires passing a run)
755
+ stage: V1Stages, optional, the version stage.
756
+ stage_conditions: List[V1StageCondition], optional, the version stage conditions.
751
757
  force: bool, optional, to force push, i.e. update if exists.
752
758
 
753
759
  Returns:
@@ -783,12 +789,18 @@ class ProjectClient:
783
789
  version_config.tags = tags
784
790
  if content:
785
791
  version_config.content = content # type: ignore
792
+ if readme is not None:
793
+ version_config.readme = readme
786
794
  if run:
787
795
  version_config.run = run
788
796
  if artifacts is not None:
789
797
  version_config.artifacts = artifacts
790
798
  if connection is not None:
791
799
  version_config.connection = connection
800
+ if stage is not None:
801
+ version_config.stage = stage
802
+ if stage_conditions is not None:
803
+ version_config.stage_conditions = stage_conditions
792
804
  return self.patch_version(
793
805
  kind=kind,
794
806
  version=version,
@@ -800,9 +812,12 @@ class ProjectClient:
800
812
  description=description,
801
813
  tags=tags,
802
814
  run=run,
815
+ readme=readme,
803
816
  artifacts=artifacts,
804
817
  connection=connection,
805
818
  content=content,
819
+ stage=stage,
820
+ stage_conditions=stage_conditions,
806
821
  )
807
822
  return self.create_version(kind=kind, data=version_config)
808
823
 
@@ -1575,3 +1590,183 @@ class ProjectClient:
1575
1590
  path=path,
1576
1591
  download_artifacts=download_artifacts,
1577
1592
  )
1593
+
1594
+ @classmethod
1595
+ @client_handler(check_no_op=True)
1596
+ def load_offline_version(
1597
+ cls,
1598
+ kind: V1ProjectVersionKind,
1599
+ version: str,
1600
+ path: str,
1601
+ project_client: Optional["ProjectClient"] = None,
1602
+ reset_project: bool = False,
1603
+ raise_if_not_found: bool = False,
1604
+ ) -> Optional["ProjectClient"]:
1605
+ """Loads a project version from a local path.
1606
+
1607
+ Args:
1608
+ kind: V1ProjectVersionKind, kind of the project version.
1609
+ version: str, required, the version name/tag.
1610
+ path: str, local path where to load the version's metadata and artifacts from.
1611
+ project_client: ProjectClient, optional,
1612
+ a project client to update with the loaded version.
1613
+ reset_project: bool, optional, to reset the project client with the loaded version.
1614
+ raise_if_not_found: bool, optional, to raise an exception if the version is not found.
1615
+
1616
+ Returns:
1617
+ ProjectClient, a project client with the loaded version.
1618
+ """
1619
+ path = ctx_paths.get_offline_path(
1620
+ entity_value=version, entity_kind=kind, path=path
1621
+ )
1622
+ version_path = "{}/{}".format(path, ctx_paths.CONTEXT_LOCAL_VERSION)
1623
+ if not os.path.exists(version_path):
1624
+ if raise_if_not_found:
1625
+ raise PolyaxonClientException(
1626
+ "Version not found in the provided path: {}".format(path)
1627
+ )
1628
+ else:
1629
+ logger.info(f"Offline data was not found: {version_path}")
1630
+ return None
1631
+
1632
+ with open(version_path, "r") as config_file:
1633
+ config_str = config_file.read()
1634
+ version_config = V1ProjectVersion(**orjson_loads(config_str))
1635
+ owner = version_config.owner
1636
+ project = version_config.project
1637
+ if project_client:
1638
+ if reset_project or not owner:
1639
+ owner = project_client.owner
1640
+ if reset_project or not project:
1641
+ project = project_client.project
1642
+ project_client._owner = owner
1643
+ project_client._project = project
1644
+ else:
1645
+ project_client = cls(
1646
+ owner=owner,
1647
+ project=project,
1648
+ )
1649
+ logger.info("Loaded version `{}`".format(version_path))
1650
+
1651
+ return project_client
1652
+
1653
+ @client_handler(check_no_op=True, check_offline=True)
1654
+ def push_version(
1655
+ self,
1656
+ kind: V1ProjectVersionKind,
1657
+ version: str,
1658
+ path: str,
1659
+ force: bool = False,
1660
+ clean: bool = False,
1661
+ ):
1662
+ """Pushes a local version from a local path to Polyaxon's API.
1663
+
1664
+ This is a generic function based on the kind passed and pushes a:
1665
+ * component version
1666
+ * model version
1667
+ * artifact version
1668
+
1669
+ Args:
1670
+ kind: V1ProjectVersionKind, kind of the project version.
1671
+ version: str, required, the version name/tag.
1672
+ path: str, optional, defaults to the offline root path,
1673
+ path where to load the metadata and artifacts from.
1674
+ force: bool, optional, to force push, i.e. update if exists.
1675
+ clean: bool, optional, to clean the version after pushing.
1676
+ """
1677
+ path = ctx_paths.get_offline_path(
1678
+ entity_value=version, entity_kind=kind, path=path
1679
+ )
1680
+ version_path = "{}/{}".format(path, ctx_paths.CONTEXT_LOCAL_VERSION)
1681
+ with open(version_path, "r") as config_file:
1682
+ config_str = config_file.read()
1683
+ version_config = V1ProjectVersion(**orjson_loads(config_str))
1684
+
1685
+ self.register_version(
1686
+ kind=kind,
1687
+ version=version,
1688
+ description=version_config.description,
1689
+ tags=version_config.tags,
1690
+ content=version_config.content,
1691
+ readme=version_config.readme,
1692
+ run=version_config.run,
1693
+ stage=version_config.stage,
1694
+ stage_conditions=version_config.stage_conditions,
1695
+ connection=version_config.connection,
1696
+ artifacts=version_config.artifacts,
1697
+ force=force,
1698
+ )
1699
+ if clean:
1700
+ delete_path(path)
1701
+
1702
+ @client_handler(check_no_op=True, check_offline=True)
1703
+ def push_component_version(
1704
+ self,
1705
+ version: str,
1706
+ path: str,
1707
+ force: bool = False,
1708
+ clean: bool = False,
1709
+ ):
1710
+ """Pushes a local component version to a remove server.
1711
+
1712
+ Args:
1713
+ version: str, required, the version name/tag.
1714
+ path: str, local path where to load the metadata and artifacts from.
1715
+ force: bool, optional, to force push, i.e. update if exists.
1716
+ clean: bool, optional, to clean the version after pushing.
1717
+ """
1718
+ return self.push_version(
1719
+ kind=V1ProjectVersionKind.COMPONENT,
1720
+ version=version,
1721
+ path=path,
1722
+ force=force,
1723
+ clean=clean,
1724
+ )
1725
+
1726
+ @client_handler(check_no_op=True, check_offline=True)
1727
+ def push_model_version(
1728
+ self,
1729
+ version: str,
1730
+ path: str,
1731
+ force: bool = True,
1732
+ clean: bool = False,
1733
+ ):
1734
+ """Pushes a local model version to a remove server.
1735
+
1736
+ Args:
1737
+ version: str, required, the version name/tag.
1738
+ path: str, local path where to load the metadata and artifacts from.
1739
+ force: bool, optional, to force push, i.e. update if exists.
1740
+ clean: bool, optional, to clean the version after pushing.
1741
+ """
1742
+ return self.pull_version(
1743
+ kind=V1ProjectVersionKind.MODEL,
1744
+ version=version,
1745
+ path=path,
1746
+ force=force,
1747
+ clean=clean,
1748
+ )
1749
+
1750
+ @client_handler(check_no_op=True, check_offline=True)
1751
+ def push_artifact_version(
1752
+ self,
1753
+ version: str,
1754
+ path: str,
1755
+ force: bool = True,
1756
+ clean: bool = False,
1757
+ ):
1758
+ """Pushes a local artifact version to a remote server.
1759
+
1760
+ Args:
1761
+ version: str, required, the version name/tag.
1762
+ path: str, local path where to load the metadata and artifacts from.
1763
+ force: bool, optional, to force push, i.e. update if exists.
1764
+ clean: bool, optional, to clean the version after pushing.
1765
+ """
1766
+ return self.pull_version(
1767
+ kind=V1ProjectVersionKind.ARTIFACT,
1768
+ version=version,
1769
+ path=path,
1770
+ force=force,
1771
+ clean=clean,
1772
+ )