proximl 0.5.17__tar.gz → 1.0.0__tar.gz

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 (157) hide show
  1. {proximl-0.5.17/proximl.egg-info → proximl-1.0.0}/PKG-INFO +2 -2
  2. {proximl-0.5.17 → proximl-1.0.0}/README.md +1 -1
  3. {proximl-0.5.17 → proximl-1.0.0}/examples/local_storage.py +0 -2
  4. {proximl-0.5.17 → proximl-1.0.0}/proximl/__init__.py +1 -1
  5. {proximl-0.5.17 → proximl-1.0.0}/proximl/checkpoints.py +56 -57
  6. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/__init__.py +6 -3
  7. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/checkpoint.py +18 -57
  8. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/dataset.py +17 -57
  9. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/job/__init__.py +11 -53
  10. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/job/create.py +51 -24
  11. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/model.py +14 -56
  12. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/volume.py +18 -57
  13. {proximl-0.5.17 → proximl-1.0.0}/proximl/datasets.py +50 -55
  14. {proximl-0.5.17 → proximl-1.0.0}/proximl/jobs.py +239 -68
  15. {proximl-0.5.17 → proximl-1.0.0}/proximl/models.py +51 -55
  16. {proximl-0.5.17 → proximl-1.0.0}/proximl/proximl.py +50 -16
  17. proximl-1.0.0/proximl/utils/__init__.py +1 -0
  18. {proximl-0.5.17/proximl → proximl-1.0.0/proximl/utils}/auth.py +4 -3
  19. proximl-1.0.0/proximl/utils/transfer.py +587 -0
  20. {proximl-0.5.17 → proximl-1.0.0}/proximl/volumes.py +48 -53
  21. {proximl-0.5.17 → proximl-1.0.0/proximl.egg-info}/PKG-INFO +2 -2
  22. {proximl-0.5.17 → proximl-1.0.0}/proximl.egg-info/SOURCES.txt +7 -5
  23. {proximl-0.5.17 → proximl-1.0.0}/proximl.egg-info/requires.txt +1 -1
  24. {proximl-0.5.17 → proximl-1.0.0}/pyproject.toml +1 -0
  25. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/test_checkpoints_integration.py +4 -3
  26. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/test_datasets_integration.py +5 -3
  27. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/test_jobs_integration.py +33 -27
  28. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/test_models_integration.py +7 -3
  29. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/test_volumes_integration.py +2 -2
  30. proximl-1.0.0/tests/unit/cli/test_cli_checkpoint_unit.py +333 -0
  31. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cloudbender/test_nodes_unit.py +112 -0
  32. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cloudbender/test_providers_unit.py +96 -0
  33. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cloudbender/test_regions_unit.py +106 -0
  34. proximl-1.0.0/tests/unit/cloudbender/test_services_unit.py +308 -0
  35. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/conftest.py +23 -10
  36. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/projects/test_project_data_connectors_unit.py +39 -0
  37. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/projects/test_project_datastores_unit.py +37 -0
  38. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/projects/test_project_members_unit.py +46 -0
  39. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/projects/test_project_services_unit.py +65 -0
  40. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/projects/test_projects_unit.py +16 -0
  41. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/test_auth_unit.py +17 -2
  42. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/test_checkpoints_unit.py +256 -71
  43. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/test_datasets_unit.py +218 -68
  44. proximl-1.0.0/tests/unit/test_exceptions.py +164 -0
  45. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/test_gpu_types_unit.py +11 -1
  46. proximl-1.0.0/tests/unit/test_jobs_unit.py +1749 -0
  47. proximl-1.0.0/tests/unit/test_main_unit.py +20 -0
  48. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/test_models_unit.py +218 -70
  49. proximl-1.0.0/tests/unit/test_proximl_unit.py +678 -0
  50. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/test_volumes_unit.py +211 -70
  51. proximl-1.0.0/tests/unit/utils/__init__.py +1 -0
  52. proximl-1.0.0/tests/unit/utils/test_transfer_unit.py +4260 -0
  53. proximl-0.5.17/proximl/cli/connection.py +0 -61
  54. proximl-0.5.17/proximl/connections.py +0 -621
  55. proximl-0.5.17/tests/unit/cli/test_cli_checkpoint_unit.py +0 -22
  56. proximl-0.5.17/tests/unit/cloudbender/test_services_unit.py +0 -167
  57. proximl-0.5.17/tests/unit/test_connections_unit.py +0 -182
  58. proximl-0.5.17/tests/unit/test_exceptions.py +0 -31
  59. proximl-0.5.17/tests/unit/test_jobs_unit.py +0 -830
  60. proximl-0.5.17/tests/unit/test_proximl_unit.py +0 -54
  61. {proximl-0.5.17 → proximl-1.0.0}/LICENSE +0 -0
  62. {proximl-0.5.17 → proximl-1.0.0}/examples/__init__.py +0 -0
  63. {proximl-0.5.17 → proximl-1.0.0}/examples/create_dataset_and_training_job.py +0 -0
  64. {proximl-0.5.17 → proximl-1.0.0}/examples/training_inference_pipeline.py +0 -0
  65. {proximl-0.5.17 → proximl-1.0.0}/proximl/__main__.py +0 -0
  66. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/cloudbender/__init__.py +0 -0
  67. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/cloudbender/data_connector.py +0 -0
  68. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/cloudbender/datastore.py +0 -0
  69. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/cloudbender/device.py +0 -0
  70. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/cloudbender/node.py +0 -0
  71. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/cloudbender/provider.py +0 -0
  72. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/cloudbender/region.py +0 -0
  73. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/cloudbender/service.py +0 -0
  74. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/environment.py +0 -0
  75. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/gpu.py +0 -0
  76. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/project/__init__.py +0 -0
  77. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/project/credential.py +0 -0
  78. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/project/data_connector.py +0 -0
  79. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/project/datastore.py +0 -0
  80. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/project/secret.py +0 -0
  81. {proximl-0.5.17 → proximl-1.0.0}/proximl/cli/project/service.py +0 -0
  82. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/__init__.py +0 -0
  83. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/cloudbender.py +0 -0
  84. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/data_connectors.py +0 -0
  85. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/datastores.py +0 -0
  86. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/device_configs.py +0 -0
  87. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/devices.py +0 -0
  88. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/nodes.py +0 -0
  89. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/providers.py +0 -0
  90. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/regions.py +0 -0
  91. {proximl-0.5.17 → proximl-1.0.0}/proximl/cloudbender/services.py +0 -0
  92. {proximl-0.5.17 → proximl-1.0.0}/proximl/environments.py +0 -0
  93. {proximl-0.5.17 → proximl-1.0.0}/proximl/exceptions.py +0 -0
  94. {proximl-0.5.17 → proximl-1.0.0}/proximl/gpu_types.py +0 -0
  95. {proximl-0.5.17 → proximl-1.0.0}/proximl/projects/__init__.py +0 -0
  96. {proximl-0.5.17 → proximl-1.0.0}/proximl/projects/credentials.py +0 -0
  97. {proximl-0.5.17 → proximl-1.0.0}/proximl/projects/data_connectors.py +0 -0
  98. {proximl-0.5.17 → proximl-1.0.0}/proximl/projects/datastores.py +0 -0
  99. {proximl-0.5.17 → proximl-1.0.0}/proximl/projects/members.py +0 -0
  100. {proximl-0.5.17 → proximl-1.0.0}/proximl/projects/projects.py +0 -0
  101. {proximl-0.5.17 → proximl-1.0.0}/proximl/projects/secrets.py +0 -0
  102. {proximl-0.5.17 → proximl-1.0.0}/proximl/projects/services.py +0 -0
  103. {proximl-0.5.17 → proximl-1.0.0}/proximl.egg-info/dependency_links.txt +0 -0
  104. {proximl-0.5.17 → proximl-1.0.0}/proximl.egg-info/entry_points.txt +0 -0
  105. {proximl-0.5.17 → proximl-1.0.0}/proximl.egg-info/top_level.txt +0 -0
  106. {proximl-0.5.17 → proximl-1.0.0}/setup.cfg +0 -0
  107. {proximl-0.5.17 → proximl-1.0.0}/setup.py +0 -0
  108. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/__init__.py +0 -0
  109. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/cloudbender/__init__.py +0 -0
  110. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/cloudbender/conftest.py +0 -0
  111. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/cloudbender/test_providers_integration.py +0 -0
  112. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/cloudbender/test_regions_integration.py +0 -0
  113. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/cloudbender/test_services_integration.py +0 -0
  114. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/conftest.py +0 -0
  115. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/projects/__init__.py +0 -0
  116. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/projects/conftest.py +0 -0
  117. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/projects/test_projects_credentials_integration.py +0 -0
  118. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/projects/test_projects_data_connectors_integration.py +0 -0
  119. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/projects/test_projects_datastores_integration.py +0 -0
  120. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/projects/test_projects_integration.py +0 -0
  121. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/projects/test_projects_members_integration.py +0 -0
  122. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/projects/test_projects_secrets_integration.py +0 -0
  123. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/projects/test_projects_services_integration.py +0 -0
  124. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/test_environments_integration.py +0 -0
  125. {proximl-0.5.17 → proximl-1.0.0}/tests/integration/test_gpu_types_integration.py +0 -0
  126. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/__init__.py +0 -0
  127. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/__init__.py +0 -0
  128. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/cloudbender/__init__.py +0 -0
  129. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/cloudbender/test_cli_datastore_unit.py +0 -0
  130. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/cloudbender/test_cli_device_unit.py +0 -0
  131. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/cloudbender/test_cli_node_unit.py +0 -0
  132. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/cloudbender/test_cli_provider_unit.py +0 -0
  133. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/cloudbender/test_cli_region_unit.py +0 -0
  134. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/cloudbender/test_cli_service_unit.py +0 -0
  135. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/conftest.py +0 -0
  136. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/projects/__init__.py +0 -0
  137. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/projects/test_cli_project_credential_unit.py +0 -0
  138. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/projects/test_cli_project_data_connector_unit.py +0 -0
  139. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/projects/test_cli_project_datastore_unit.py +0 -0
  140. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/projects/test_cli_project_secret_unit.py +0 -0
  141. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/projects/test_cli_project_service_unit.py +0 -0
  142. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/projects/test_cli_project_unit.py +0 -0
  143. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/test_cli_datasets_unit.py +0 -0
  144. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/test_cli_environment_unit.py +0 -0
  145. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/test_cli_gpu_unit.py +0 -0
  146. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/test_cli_job_unit.py +0 -0
  147. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/test_cli_model_unit.py +0 -0
  148. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cli/test_cli_volume_unit.py +0 -0
  149. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cloudbender/__init__.py +0 -0
  150. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cloudbender/test_data_connectors_unit.py +0 -0
  151. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cloudbender/test_datastores_unit.py +0 -0
  152. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cloudbender/test_device_configs_unit.py +0 -0
  153. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/cloudbender/test_devices_unit.py +0 -0
  154. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/projects/__init__.py +0 -0
  155. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/projects/test_project_credentials_unit.py +0 -0
  156. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/projects/test_project_secrets_unit.py +0 -0
  157. {proximl-0.5.17 → proximl-1.0.0}/tests/unit/test_environments_unit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: proximl
3
- Version: 0.5.17
3
+ Version: 1.0.0
4
4
  Summary: proxiML client SDK and command line utilities
5
5
  Home-page: https://github.com/proxiML/python-sdk
6
6
  Author: proxiML
@@ -177,7 +177,7 @@ Description: <div align="center">
177
177
  proximl dataset list
178
178
  ```
179
179
 
180
- To connect to a job that requires the [connection capability](https://docs.proximl.ai/reference/connection-capability):
180
+ To connect to a job that uses the "local" file transfer method:
181
181
 
182
182
  ```
183
183
  proximl job connect <job ID or name>
@@ -169,7 +169,7 @@ To list all datasets:
169
169
  proximl dataset list
170
170
  ```
171
171
 
172
- To connect to a job that requires the [connection capability](https://docs.proximl.ai/reference/connection-capability):
172
+ To connect to a job that uses the "local" file transfer method:
173
173
 
174
174
  ```
175
175
  proximl job connect <job ID or name>
@@ -19,7 +19,6 @@ async def create_dataset():
19
19
  attach_task = asyncio.create_task(dataset.attach())
20
20
  connect_task = asyncio.create_task(dataset.connect())
21
21
  await asyncio.gather(attach_task, connect_task)
22
- await dataset.disconnect()
23
22
  return dataset
24
23
 
25
24
 
@@ -55,7 +54,6 @@ async def run_job(dataset):
55
54
  await asyncio.gather(attach_task, connect_task)
56
55
 
57
56
  # Cleanup job
58
- await job.disconnect()
59
57
  await job.remove()
60
58
 
61
59
 
@@ -13,5 +13,5 @@ logging.basicConfig(
13
13
  logger = logging.getLogger(__name__)
14
14
 
15
15
 
16
- __version__ = "0.5.17"
16
+ __version__ = "1.0.0"
17
17
  __all__ = "ProxiML"
@@ -10,7 +10,7 @@ from .exceptions import (
10
10
  SpecificationError,
11
11
  ProxiMLException,
12
12
  )
13
- from .connections import Connection
13
+ from proximl.utils.transfer import upload, download
14
14
 
15
15
 
16
16
  class Checkpoints(object):
@@ -23,7 +23,9 @@ class Checkpoints(object):
23
23
 
24
24
  async def list(self, **kwargs):
25
25
  resp = await self.proximl._query(f"/checkpoint", "GET", kwargs)
26
- checkpoints = [Checkpoint(self.proximl, **checkpoint) for checkpoint in resp]
26
+ checkpoints = [
27
+ Checkpoint(self.proximl, **checkpoint) for checkpoint in resp
28
+ ]
27
29
  return checkpoints
28
30
 
29
31
  async def list_public(self, **kwargs):
@@ -68,13 +70,17 @@ class Checkpoint:
68
70
  def __init__(self, proximl, **kwargs):
69
71
  self.proximl = proximl
70
72
  self._checkpoint = kwargs
71
- self._id = self._checkpoint.get("id", self._checkpoint.get("checkpoint_uuid"))
73
+ self._id = self._checkpoint.get(
74
+ "id", self._checkpoint.get("checkpoint_uuid")
75
+ )
72
76
  self._status = self._checkpoint.get("status")
73
77
  self._name = self._checkpoint.get("name")
74
- self._size = self._checkpoint.get("size") or self._checkpoint.get("used_size")
75
- self._billed_size = self._checkpoint.get("billed_size") or self._checkpoint.get(
76
- "size"
78
+ self._size = self._checkpoint.get("size") or self._checkpoint.get(
79
+ "used_size"
77
80
  )
81
+ self._billed_size = self._checkpoint.get(
82
+ "billed_size"
83
+ ) or self._checkpoint.get("size")
78
84
  self._project_uuid = self._checkpoint.get("project_uuid")
79
85
 
80
86
  @property
@@ -122,56 +128,45 @@ class Checkpoint:
122
128
  )
123
129
  return resp
124
130
 
125
- async def get_connection_utility_url(self):
126
- resp = await self.proximl._query(
127
- f"/checkpoint/{self._id}/download",
128
- "GET",
129
- dict(project_uuid=self._project_uuid),
130
- )
131
- return resp
132
-
133
- def get_connection_details(self):
134
- if self._checkpoint.get("vpn"):
135
- details = dict(
136
- entity_type="checkpoint",
137
- project_uuid=self._checkpoint.get("project_uuid"),
138
- cidr=self._checkpoint.get("vpn").get("cidr"),
139
- ssh_port=self._checkpoint.get("vpn").get("client").get("ssh_port"),
140
- input_path=(
141
- self._checkpoint.get("source_uri")
142
- if self.status in ["new", "downloading"]
143
- else None
144
- ),
145
- output_path=(
146
- self._checkpoint.get("output_uri")
147
- if self.status == "exporting"
148
- else None
149
- ),
150
- )
151
- else:
152
- details = dict()
153
- return details
154
-
155
131
  async def connect(self):
156
- if self.status in ["ready", "failed"]:
157
- raise SpecificationError(
158
- "status",
159
- f"You can only connect to downloading or exporting checkpoints.",
160
- )
161
- if self.status == "new":
162
- await self.wait_for("downloading")
163
- connection = Connection(
164
- self.proximl, entity_type="checkpoint", id=self.id, entity=self
165
- )
166
- await connection.start()
167
- return connection.status
132
+ if self.status not in ["downloading", "exporting"]:
133
+ if self.status == "new":
134
+ await self.wait_for("downloading")
135
+ else:
136
+ raise SpecificationError(
137
+ "status",
138
+ f"You can only connect to downloading or exporting checkpoints.",
139
+ )
168
140
 
169
- async def disconnect(self):
170
- connection = Connection(
171
- self.proximl, entity_type="checkpoint", id=self.id, entity=self
172
- )
173
- await connection.stop()
174
- return connection.status
141
+ # Refresh to get latest entity data
142
+ await self.refresh()
143
+
144
+ if self.status == "downloading":
145
+ # Upload task - get auth_token, hostname, and source_uri from checkpoint
146
+ auth_token = self._checkpoint.get("auth_token")
147
+ hostname = self._checkpoint.get("hostname")
148
+ source_uri = self._checkpoint.get("source_uri")
149
+
150
+ if not auth_token or not hostname or not source_uri:
151
+ raise SpecificationError(
152
+ "status",
153
+ f"Checkpoint in downloading status missing required connection properties (auth_token, hostname, source_uri).",
154
+ )
155
+
156
+ await upload(hostname, auth_token, source_uri)
157
+ elif self.status == "exporting":
158
+ # Download task - get auth_token, hostname, and output_uri from checkpoint
159
+ auth_token = self._checkpoint.get("auth_token")
160
+ hostname = self._checkpoint.get("hostname")
161
+ output_uri = self._checkpoint.get("output_uri")
162
+
163
+ if not auth_token or not hostname or not output_uri:
164
+ raise SpecificationError(
165
+ "status",
166
+ f"Checkpoint in exporting status missing required connection properties (auth_token, hostname, output_uri).",
167
+ )
168
+
169
+ await download(hostname, auth_token, output_uri)
175
170
 
176
171
  async def remove(self, force=False):
177
172
  await self.proximl._query(
@@ -210,7 +205,9 @@ class Checkpoint:
210
205
  if msg_handler:
211
206
  msg_handler(data)
212
207
  else:
213
- timestamp = datetime.fromtimestamp(int(data.get("time")) / 1000)
208
+ timestamp = datetime.fromtimestamp(
209
+ int(data.get("time")) / 1000
210
+ )
214
211
  print(
215
212
  f"{timestamp.strftime('%m/%d/%Y, %H:%M:%S')}: {data.get('msg').rstrip()}"
216
213
  )
@@ -239,7 +236,7 @@ class Checkpoint:
239
236
  async def wait_for(self, status, timeout=300):
240
237
  if self.status == status:
241
238
  return
242
- valid_statuses = ["downloading", "ready", "archived"]
239
+ valid_statuses = ["downloading", "ready", "exporting", "archived"]
243
240
  if not status in valid_statuses:
244
241
  raise SpecificationError(
245
242
  "status",
@@ -254,7 +251,9 @@ class Checkpoint:
254
251
  )
255
252
  POLL_INTERVAL_MIN = 5
256
253
  POLL_INTERVAL_MAX = 60
257
- POLL_INTERVAL = max(min(timeout / 60, POLL_INTERVAL_MAX), POLL_INTERVAL_MIN)
254
+ POLL_INTERVAL = max(
255
+ min(timeout / 60, POLL_INTERVAL_MAX), POLL_INTERVAL_MIN
256
+ )
258
257
  retry_count = math.ceil(timeout / POLL_INTERVAL)
259
258
  count = 0
260
259
  while count < retry_count:
@@ -142,7 +142,9 @@ def configure(config):
142
142
  project for project in projects if project.id == active_project_id
143
143
  ]
144
144
 
145
- active_project_name = active_project[0].name if len(active_project) else "UNSET"
145
+ active_project_name = (
146
+ active_project[0].name if len(active_project) else "UNSET"
147
+ )
146
148
 
147
149
  click.echo(f"Current Active Project: {active_project_name}")
148
150
 
@@ -152,11 +154,12 @@ def configure(config):
152
154
  show_choices=True,
153
155
  default=active_project_name,
154
156
  )
155
- selected_project = [project for project in projects if project.name == name]
157
+ selected_project = [
158
+ project for project in projects if project.name == name
159
+ ]
156
160
  config.proximl.client.set_active_project(selected_project[0].id)
157
161
 
158
162
 
159
- from proximl.cli.connection import connection
160
163
  from proximl.cli.dataset import dataset
161
164
  from proximl.cli.model import model
162
165
  from proximl.cli.checkpoint import checkpoint
@@ -35,15 +35,7 @@ def attach(config, checkpoint):
35
35
  if None is found:
36
36
  raise click.UsageError("Cannot find specified checkpoint.")
37
37
 
38
- try:
39
- config.proximl.run(found.attach())
40
- return config.proximl.run(found.disconnect())
41
- except:
42
- try:
43
- config.proximl.run(found.disconnect())
44
- except:
45
- pass
46
- raise
38
+ config.proximl.run(found.attach())
47
39
 
48
40
 
49
41
  @checkpoint.command()
@@ -67,18 +59,10 @@ def connect(config, checkpoint, attach):
67
59
  if None is found:
68
60
  raise click.UsageError("Cannot find specified checkpoint.")
69
61
 
70
- try:
71
- if attach:
72
- config.proximl.run(found.connect(), found.attach())
73
- return config.proximl.run(found.disconnect())
74
- else:
75
- return config.proximl.run(found.connect())
76
- except:
77
- try:
78
- config.proximl.run(found.disconnect())
79
- except:
80
- pass
81
- raise
62
+ if attach:
63
+ config.proximl.run(found.connect(), found.attach())
64
+ else:
65
+ config.proximl.run(found.connect())
82
66
 
83
67
 
84
68
  @checkpoint.command()
@@ -123,41 +107,15 @@ def create(config, attach, connect, source, name, path):
123
107
  )
124
108
  )
125
109
 
126
- try:
127
- if connect and attach:
128
- config.proximl.run(checkpoint.attach(), checkpoint.connect())
129
- return config.proximl.run(checkpoint.disconnect())
130
- elif connect:
131
- return config.proximl.run(checkpoint.connect())
132
- else:
133
- raise click.UsageError(
134
- "Abort!\n"
135
- "No logs to show for local sourced checkpoint without connect."
136
- )
137
- except:
138
- try:
139
- config.proximl.run(checkpoint.disconnect())
140
- except:
141
- pass
142
- raise
143
-
144
-
145
- @checkpoint.command()
146
- @click.argument("checkpoint", type=click.STRING)
147
- @pass_config
148
- def disconnect(config, checkpoint):
149
- """
150
- Disconnect and clean-up checkpoint upload.
151
-
152
- CHECKPOINT may be specified by name or ID, but ID is preferred.
153
- """
154
- checkpoints = config.proximl.run(config.proximl.client.checkpoints.list())
155
-
156
- found = search_by_id_name(checkpoint, checkpoints)
157
- if None is found:
158
- raise click.UsageError("Cannot find specified checkpoint.")
159
-
160
- return config.proximl.run(found.disconnect())
110
+ if connect and attach:
111
+ config.proximl.run(checkpoint.attach(), checkpoint.connect())
112
+ elif connect:
113
+ config.proximl.run(checkpoint.connect())
114
+ else:
115
+ raise click.UsageError(
116
+ "Abort!\n"
117
+ "No logs to show for local sourced checkpoint without connect."
118
+ )
161
119
 
162
120
 
163
121
  @checkpoint.command()
@@ -236,7 +194,10 @@ def remove(config, checkpoint, force):
236
194
  found = search_by_id_name(checkpoint, checkpoints)
237
195
  if None is found:
238
196
  if force:
239
- config.proximl.run(found.client.checkpoints.remove(checkpoint))
197
+ config.proximl.run(
198
+ config.proximl.client.checkpoints.remove(checkpoint)
199
+ )
200
+ return
240
201
  else:
241
202
  raise click.UsageError("Cannot find specified checkpoint.")
242
203
 
@@ -35,15 +35,7 @@ def attach(config, dataset):
35
35
  if None is found:
36
36
  raise click.UsageError("Cannot find specified dataset.")
37
37
 
38
- try:
39
- config.proximl.run(found.attach())
40
- return config.proximl.run(found.disconnect())
41
- except:
42
- try:
43
- config.proximl.run(found.disconnect())
44
- except:
45
- pass
46
- raise
38
+ config.proximl.run(found.attach())
47
39
 
48
40
 
49
41
  @dataset.command()
@@ -67,18 +59,10 @@ def connect(config, dataset, attach):
67
59
  if None is found:
68
60
  raise click.UsageError("Cannot find specified dataset.")
69
61
 
70
- try:
71
- if attach:
72
- config.proximl.run(found.connect(), found.attach())
73
- return config.proximl.run(found.disconnect())
74
- else:
75
- return config.proximl.run(found.connect())
76
- except:
77
- try:
78
- config.proximl.run(found.disconnect())
79
- except:
80
- pass
81
- raise
62
+ if attach:
63
+ config.proximl.run(found.connect(), found.attach())
64
+ else:
65
+ config.proximl.run(found.connect())
82
66
 
83
67
 
84
68
  @dataset.command()
@@ -123,41 +107,15 @@ def create(config, attach, connect, source, name, path):
123
107
  )
124
108
  )
125
109
 
126
- try:
127
- if connect and attach:
128
- config.proximl.run(dataset.attach(), dataset.connect())
129
- return config.proximl.run(dataset.disconnect())
130
- elif connect:
131
- return config.proximl.run(dataset.connect())
132
- else:
133
- raise click.UsageError(
134
- "Abort!\n"
135
- "No logs to show for local sourced dataset without connect."
136
- )
137
- except:
138
- try:
139
- config.proximl.run(dataset.disconnect())
140
- except:
141
- pass
142
- raise
143
-
144
-
145
- @dataset.command()
146
- @click.argument("dataset", type=click.STRING)
147
- @pass_config
148
- def disconnect(config, dataset):
149
- """
150
- Disconnect and clean-up dataset upload.
151
-
152
- DATASET may be specified by name or ID, but ID is preferred.
153
- """
154
- datasets = config.proximl.run(config.proximl.client.datasets.list())
155
-
156
- found = search_by_id_name(dataset, datasets)
157
- if None is found:
158
- raise click.UsageError("Cannot find specified dataset.")
159
-
160
- return config.proximl.run(found.disconnect())
110
+ if connect and attach:
111
+ config.proximl.run(dataset.attach(), dataset.connect())
112
+ elif connect:
113
+ config.proximl.run(dataset.connect())
114
+ else:
115
+ raise click.UsageError(
116
+ "Abort!\n"
117
+ "No logs to show for local sourced dataset without connect."
118
+ )
161
119
 
162
120
 
163
121
  @dataset.command()
@@ -252,7 +210,9 @@ def rename(config, dataset, name):
252
210
  DATASET may be specified by name or ID, but ID is preferred.
253
211
  """
254
212
  try:
255
- dataset = config.proximl.run(config.proximl.client.datasets.get(dataset))
213
+ dataset = config.proximl.run(
214
+ config.proximl.client.datasets.get(dataset)
215
+ )
256
216
  if dataset is None:
257
217
  raise click.UsageError("Cannot find specified dataset.")
258
218
  except:
@@ -25,15 +25,7 @@ def attach(config, job):
25
25
  if None is found:
26
26
  raise click.UsageError("Cannot find specified job.")
27
27
 
28
- try:
29
- config.proximl.run(found.attach())
30
- return config.proximl.run(found.disconnect())
31
- except:
32
- try:
33
- config.proximl.run(found.disconnect())
34
- except:
35
- pass
36
- raise
28
+ config.proximl.run(found.attach())
37
29
 
38
30
 
39
31
  @job.command()
@@ -58,38 +50,22 @@ def connect(config, job, attach):
58
50
  raise click.UsageError("Cannot find specified job.")
59
51
 
60
52
  if found.type != "notebook":
61
- try:
62
- if attach:
63
- config.proximl.run(found.connect(), found.attach())
64
- return config.proximl.run(found.disconnect())
65
- else:
66
- return config.proximl.run(found.connect())
67
- except:
68
- try:
69
- config.proximl.run(found.disconnect())
70
- except:
71
- pass
72
- raise
53
+ if attach:
54
+ config.proximl.run(found.connect(), found.attach())
55
+ else:
56
+ config.proximl.run(found.connect())
73
57
  else:
74
58
  if found.status in [
75
59
  "new",
76
60
  "waiting for data/model download",
77
61
  "waiting for GPUs",
78
62
  ]:
79
- try:
80
- if attach:
81
- config.proximl.run(found.connect(), found.attach())
82
- config.proximl.run(found.disconnect())
83
- click.echo("Launching...", file=config.stdout)
84
- browse(found.notebook_url)
85
- else:
86
- return config.proximl.run(found.connect())
87
- except:
88
- try:
89
- config.proximl.run(found.disconnect())
90
- except:
91
- pass
92
- raise
63
+ if attach:
64
+ config.proximl.run(found.connect(), found.attach())
65
+ click.echo("Launching...", file=config.stdout)
66
+ browse(found.notebook_url)
67
+ else:
68
+ config.proximl.run(found.connect())
93
69
  elif found.status not in [
94
70
  "starting",
95
71
  "running",
@@ -103,24 +79,6 @@ def connect(config, job, attach):
103
79
  browse(found.notebook_url)
104
80
 
105
81
 
106
- @job.command()
107
- @click.argument("job", type=click.STRING)
108
- @pass_config
109
- def disconnect(config, job):
110
- """
111
- Disconnect and clean-up job.
112
-
113
- JOB may be specified by name or ID, but ID is preferred.
114
- """
115
- jobs = config.proximl.run(config.proximl.client.jobs.list())
116
-
117
- found = search_by_id_name(job, jobs)
118
- if None is found:
119
- raise click.UsageError("Cannot find specified job.")
120
-
121
- return config.proximl.run(found.disconnect())
122
-
123
-
124
82
  @job.command()
125
83
  @click.option(
126
84
  "--wait/--no-wait",