proximl 0.5.17__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- examples/local_storage.py +0 -2
- proximl/__init__.py +1 -1
- proximl/checkpoints.py +56 -57
- proximl/cli/__init__.py +6 -3
- proximl/cli/checkpoint.py +18 -57
- proximl/cli/dataset.py +17 -57
- proximl/cli/job/__init__.py +11 -53
- proximl/cli/job/create.py +51 -24
- proximl/cli/model.py +14 -56
- proximl/cli/volume.py +18 -57
- proximl/datasets.py +50 -55
- proximl/jobs.py +239 -68
- proximl/models.py +51 -55
- proximl/proximl.py +50 -16
- proximl/utils/__init__.py +1 -0
- proximl/{auth.py → utils/auth.py} +4 -3
- proximl/utils/transfer.py +587 -0
- proximl/volumes.py +48 -53
- {proximl-0.5.17.dist-info → proximl-1.0.0.dist-info}/METADATA +3 -3
- {proximl-0.5.17.dist-info → proximl-1.0.0.dist-info}/RECORD +52 -50
- tests/integration/test_checkpoints_integration.py +4 -3
- tests/integration/test_datasets_integration.py +5 -3
- tests/integration/test_jobs_integration.py +33 -27
- tests/integration/test_models_integration.py +7 -3
- tests/integration/test_volumes_integration.py +2 -2
- tests/unit/cli/test_cli_checkpoint_unit.py +312 -1
- tests/unit/cloudbender/test_nodes_unit.py +112 -0
- tests/unit/cloudbender/test_providers_unit.py +96 -0
- tests/unit/cloudbender/test_regions_unit.py +106 -0
- tests/unit/cloudbender/test_services_unit.py +141 -0
- tests/unit/conftest.py +23 -10
- tests/unit/projects/test_project_data_connectors_unit.py +39 -0
- tests/unit/projects/test_project_datastores_unit.py +37 -0
- tests/unit/projects/test_project_members_unit.py +46 -0
- tests/unit/projects/test_project_services_unit.py +65 -0
- tests/unit/projects/test_projects_unit.py +16 -0
- tests/unit/test_auth_unit.py +17 -2
- tests/unit/test_checkpoints_unit.py +256 -71
- tests/unit/test_datasets_unit.py +218 -68
- tests/unit/test_exceptions.py +133 -0
- tests/unit/test_gpu_types_unit.py +11 -1
- tests/unit/test_jobs_unit.py +1014 -95
- tests/unit/test_main_unit.py +20 -0
- tests/unit/test_models_unit.py +218 -70
- tests/unit/test_proximl_unit.py +627 -3
- tests/unit/test_volumes_unit.py +211 -70
- tests/unit/utils/__init__.py +1 -0
- tests/unit/utils/test_transfer_unit.py +4260 -0
- proximl/cli/connection.py +0 -61
- proximl/connections.py +0 -621
- tests/unit/test_connections_unit.py +0 -182
- {proximl-0.5.17.dist-info → proximl-1.0.0.dist-info}/LICENSE +0 -0
- {proximl-0.5.17.dist-info → proximl-1.0.0.dist-info}/WHEEL +0 -0
- {proximl-0.5.17.dist-info → proximl-1.0.0.dist-info}/entry_points.txt +0 -0
- {proximl-0.5.17.dist-info → proximl-1.0.0.dist-info}/top_level.txt +0 -0
proximl/volumes.py
CHANGED
|
@@ -10,7 +10,7 @@ from .exceptions import (
|
|
|
10
10
|
SpecificationError,
|
|
11
11
|
ProxiMLException,
|
|
12
12
|
)
|
|
13
|
-
from .
|
|
13
|
+
from proximl.utils.transfer import upload, download
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class Volumes(object):
|
|
@@ -56,7 +56,9 @@ class Volumes(object):
|
|
|
56
56
|
return volume
|
|
57
57
|
|
|
58
58
|
async def remove(self, id, **kwargs):
|
|
59
|
-
await self.proximl._query(
|
|
59
|
+
await self.proximl._query(
|
|
60
|
+
f"/volume/{id}", "DELETE", dict(**kwargs, force=True)
|
|
61
|
+
)
|
|
60
62
|
|
|
61
63
|
|
|
62
64
|
class Volume:
|
|
@@ -120,56 +122,45 @@ class Volume:
|
|
|
120
122
|
)
|
|
121
123
|
return resp
|
|
122
124
|
|
|
123
|
-
async def get_connection_utility_url(self):
|
|
124
|
-
resp = await self.proximl._query(
|
|
125
|
-
f"/volume/{self._id}/download",
|
|
126
|
-
"GET",
|
|
127
|
-
dict(project_uuid=self._project_uuid),
|
|
128
|
-
)
|
|
129
|
-
return resp
|
|
130
|
-
|
|
131
|
-
def get_connection_details(self):
|
|
132
|
-
if self._volume.get("vpn"):
|
|
133
|
-
details = dict(
|
|
134
|
-
entity_type="volume",
|
|
135
|
-
project_uuid=self._volume.get("project_uuid"),
|
|
136
|
-
cidr=self._volume.get("vpn").get("cidr"),
|
|
137
|
-
ssh_port=self._volume.get("vpn").get("client").get("ssh_port"),
|
|
138
|
-
input_path=(
|
|
139
|
-
self._volume.get("source_uri")
|
|
140
|
-
if self.status in ["new", "downloading"]
|
|
141
|
-
else None
|
|
142
|
-
),
|
|
143
|
-
output_path=(
|
|
144
|
-
self._volume.get("output_uri")
|
|
145
|
-
if self.status == "exporting"
|
|
146
|
-
else None
|
|
147
|
-
),
|
|
148
|
-
)
|
|
149
|
-
else:
|
|
150
|
-
details = dict()
|
|
151
|
-
return details
|
|
152
|
-
|
|
153
125
|
async def connect(self):
|
|
154
|
-
if self.status in ["
|
|
155
|
-
|
|
156
|
-
"
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
self.proximl, entity_type="volume", id=self.id, entity=self
|
|
163
|
-
)
|
|
164
|
-
await connection.start()
|
|
165
|
-
return connection.status
|
|
126
|
+
if self.status not in ["downloading", "exporting"]:
|
|
127
|
+
if self.status == "new":
|
|
128
|
+
await self.wait_for("downloading")
|
|
129
|
+
else:
|
|
130
|
+
raise SpecificationError(
|
|
131
|
+
"status",
|
|
132
|
+
f"You can only connect to downloading or exporting volumes.",
|
|
133
|
+
)
|
|
166
134
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
135
|
+
# Refresh to get latest entity data
|
|
136
|
+
await self.refresh()
|
|
137
|
+
|
|
138
|
+
if self.status == "downloading":
|
|
139
|
+
# Upload task - get auth_token, hostname, and source_uri from volume
|
|
140
|
+
auth_token = self._volume.get("auth_token")
|
|
141
|
+
hostname = self._volume.get("hostname")
|
|
142
|
+
source_uri = self._volume.get("source_uri")
|
|
143
|
+
|
|
144
|
+
if not auth_token or not hostname or not source_uri:
|
|
145
|
+
raise SpecificationError(
|
|
146
|
+
"status",
|
|
147
|
+
f"Volume in downloading status missing required connection properties (auth_token, hostname, source_uri).",
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
await upload(hostname, auth_token, source_uri)
|
|
151
|
+
elif self.status == "exporting":
|
|
152
|
+
# Download task - get auth_token, hostname, and output_uri from volume
|
|
153
|
+
auth_token = self._volume.get("auth_token")
|
|
154
|
+
hostname = self._volume.get("hostname")
|
|
155
|
+
output_uri = self._volume.get("output_uri")
|
|
156
|
+
|
|
157
|
+
if not auth_token or not hostname or not output_uri:
|
|
158
|
+
raise SpecificationError(
|
|
159
|
+
"status",
|
|
160
|
+
f"Volume in exporting status missing required connection properties (auth_token, hostname, output_uri).",
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
await download(hostname, auth_token, output_uri)
|
|
173
164
|
|
|
174
165
|
async def remove(self, force=False):
|
|
175
166
|
await self.proximl._query(
|
|
@@ -208,7 +199,9 @@ class Volume:
|
|
|
208
199
|
if msg_handler:
|
|
209
200
|
msg_handler(data)
|
|
210
201
|
else:
|
|
211
|
-
timestamp = datetime.fromtimestamp(
|
|
202
|
+
timestamp = datetime.fromtimestamp(
|
|
203
|
+
int(data.get("time")) / 1000
|
|
204
|
+
)
|
|
212
205
|
print(
|
|
213
206
|
f"{timestamp.strftime('%m/%d/%Y, %H:%M:%S')}: {data.get('msg').rstrip()}"
|
|
214
207
|
)
|
|
@@ -237,7 +230,7 @@ class Volume:
|
|
|
237
230
|
async def wait_for(self, status, timeout=300):
|
|
238
231
|
if self.status == status:
|
|
239
232
|
return
|
|
240
|
-
valid_statuses = ["downloading", "ready", "archived"]
|
|
233
|
+
valid_statuses = ["downloading", "ready", "exporting", "archived"]
|
|
241
234
|
if not status in valid_statuses:
|
|
242
235
|
raise SpecificationError(
|
|
243
236
|
"status",
|
|
@@ -252,7 +245,9 @@ class Volume:
|
|
|
252
245
|
)
|
|
253
246
|
POLL_INTERVAL_MIN = 5
|
|
254
247
|
POLL_INTERVAL_MAX = 60
|
|
255
|
-
POLL_INTERVAL = max(
|
|
248
|
+
POLL_INTERVAL = max(
|
|
249
|
+
min(timeout / 60, POLL_INTERVAL_MAX), POLL_INTERVAL_MIN
|
|
250
|
+
)
|
|
256
251
|
retry_count = math.ceil(timeout / POLL_INTERVAL)
|
|
257
252
|
count = 0
|
|
258
253
|
while count < retry_count:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: proximl
|
|
3
|
-
Version: 0.
|
|
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
|
|
@@ -12,8 +12,8 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.8
|
|
13
13
|
Requires-Python: >=3.8
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
|
-
Requires-Dist: aiodocker
|
|
16
15
|
Requires-Dist: aiohttp
|
|
16
|
+
Requires-Dist: aiofiles
|
|
17
17
|
Requires-Dist: boto3
|
|
18
18
|
Requires-Dist: Click (>8)
|
|
19
19
|
Requires-Dist: python-jose[cryptography]
|
|
@@ -190,7 +190,7 @@ To list all datasets:
|
|
|
190
190
|
proximl dataset list
|
|
191
191
|
```
|
|
192
192
|
|
|
193
|
-
To connect to a job that
|
|
193
|
+
To connect to a job that uses the "local" file transfer method:
|
|
194
194
|
|
|
195
195
|
```
|
|
196
196
|
proximl job connect <job ID or name>
|
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
examples/create_dataset_and_training_job.py,sha256=Fqueoz2KD1MTxnU960iqHUdxvo68Xe64HT5XS55lI9w,1178
|
|
3
|
-
examples/local_storage.py,sha256=
|
|
3
|
+
examples/local_storage.py,sha256=1_bvGoE04ttvKT5MH7Vm8VFiJrw6nF_S7FojlcdC3kY,1687
|
|
4
4
|
examples/training_inference_pipeline.py,sha256=pxux0QUUtRXxKj2rX-6fPEKBIi43mhRd1zJ-Lf1ZJGI,2334
|
|
5
|
-
proximl/__init__.py,sha256=
|
|
5
|
+
proximl/__init__.py,sha256=6bDDwARPoJxFWPJex__P6-Qdw49mnh_w-YXWnlVLSYg,432
|
|
6
6
|
proximl/__main__.py,sha256=JgErYkiskih8Y6oRwowALtR-rwQhAAdqOYWjQraRIPI,59
|
|
7
|
-
proximl/
|
|
8
|
-
proximl/
|
|
9
|
-
proximl/connections.py,sha256=0C8VJSkDturQVlzg_3yAkQz8W9NAmgzDCBRK_SrzeUI,20035
|
|
10
|
-
proximl/datasets.py,sha256=dBDzf7DZ1rS5LmJPy5oV-JC0PXGTf-NZuBDG1KPyoA4,8600
|
|
7
|
+
proximl/checkpoints.py,sha256=SClBmtCUM4Ql8DWEDw4mpDERJAXE7z9ZnYqEcTwsr-g,8924
|
|
8
|
+
proximl/datasets.py,sha256=m2rza1wdRx0DPWc7cHWcf7J1FNdMrWV59Yxlq7ouVYU,8690
|
|
11
9
|
proximl/environments.py,sha256=L_cRmau1wJxpGvnJAqgms-GiNdDhiuOntrlBqsdoE3A,1507
|
|
12
10
|
proximl/exceptions.py,sha256=q1YfsqbLw3y1DJHP1FcMM8xG5CEhQsTIvRfq4v5PyVw,5468
|
|
13
11
|
proximl/gpu_types.py,sha256=V-EZzE-hDLi5eVQ2_9yGLTm8-Qk1AnnzctfSVC44yLY,1901
|
|
14
|
-
proximl/jobs.py,sha256=
|
|
15
|
-
proximl/models.py,sha256=
|
|
16
|
-
proximl/proximl.py,sha256=
|
|
17
|
-
proximl/volumes.py,sha256=
|
|
18
|
-
proximl/cli/__init__.py,sha256=
|
|
19
|
-
proximl/cli/checkpoint.py,sha256=
|
|
20
|
-
proximl/cli/
|
|
21
|
-
proximl/cli/dataset.py,sha256=ueoeicBY8aMLpvpKUIBICnS9GsEnDOj7ZlFmOfjjY4c,6871
|
|
12
|
+
proximl/jobs.py,sha256=lBj1UGPKDQAPbQEAUQ5lPL4-35wHNVDQVUGdtoE8G5Q,24928
|
|
13
|
+
proximl/models.py,sha256=ZigU31SdpsxsnkW5wMt4narvlqVO5MbxTQuV__Mndqo,8339
|
|
14
|
+
proximl/proximl.py,sha256=x0P7D6iMKl1nXWCWMzaHhFo63oxb7RWhf1KPa9zUOkA,12724
|
|
15
|
+
proximl/volumes.py,sha256=uQDVLLJa_-GNdxwo8xh67KcGhlJ8EMHtW_V3B9IfgWA,8533
|
|
16
|
+
proximl/cli/__init__.py,sha256=vtNYq0HJ491CWMjIevCVSnLilCIDQv9LBhZmVWv9N3c,4330
|
|
17
|
+
proximl/cli/checkpoint.py,sha256=mgEQ13XO9FS1SOXW4hTfbN2cqAYY7izSWt2KyrEITJQ,6020
|
|
18
|
+
proximl/cli/dataset.py,sha256=MpAC-AvXXEZXr1PE0ch5TPq1U8v2fecbrTQcvJ8Lhcc,5721
|
|
22
19
|
proximl/cli/environment.py,sha256=nh7oYbG5oOrZEpZkMkKgvzFXmQJWnFTMw1-YbuvkdFU,1019
|
|
23
20
|
proximl/cli/gpu.py,sha256=xL8eqM5ca_Ueaj8cWit1iKn34KhaR0StrubVeRU2YQY,883
|
|
24
|
-
proximl/cli/model.py,sha256=
|
|
25
|
-
proximl/cli/volume.py,sha256=
|
|
21
|
+
proximl/cli/model.py,sha256=n6hghRf3Krj1K39UD6xg8UvTGIax0XxXrx7hGe8TiSY,4963
|
|
22
|
+
proximl/cli/volume.py,sha256=lACn2vG0R1NMfGLRHl6t9oSUZI2twouv3Y-N3kwri_Q,5135
|
|
26
23
|
proximl/cli/cloudbender/__init__.py,sha256=ATPj85Be6o4xw8M6vvHfkuLyw1drc_0IlCMh1wSebYQ,592
|
|
27
24
|
proximl/cli/cloudbender/data_connector.py,sha256=D5xbUzpUGpn_NN-NZQ9vSxOZY610c1LsoBC40DkPwkw,3606
|
|
28
25
|
proximl/cli/cloudbender/datastore.py,sha256=YBFbobEKjw3s5uYC1krD_Oa-VEz3kjQ5UvPOqkq-NJE,3323
|
|
@@ -31,8 +28,8 @@ proximl/cli/cloudbender/node.py,sha256=xxzj68YvpRey2vZQasgYTnwv3x7TnwpuPSSf8Ma5a
|
|
|
31
28
|
proximl/cli/cloudbender/provider.py,sha256=qhWbDK1tWi00wQWEYqGw7yGoZx0nEjV40GLHRuuE86c,1726
|
|
32
29
|
proximl/cli/cloudbender/region.py,sha256=WnSkY4dXKRJ-FNaoxMfmoh6iuUx5dXCNJmEFT34Xtao,2892
|
|
33
30
|
proximl/cli/cloudbender/service.py,sha256=6NuwlFULJLtOmMy9OFA8GkW4MLvNemAcd_KitQyDXV8,3147
|
|
34
|
-
proximl/cli/job/__init__.py,sha256=
|
|
35
|
-
proximl/cli/job/create.py,sha256=
|
|
31
|
+
proximl/cli/job/__init__.py,sha256=IaoNWZUn4VHHahTaAk9z7Vr4CXzHk4v3RWHzPcEZP-8,5379
|
|
32
|
+
proximl/cli/job/create.py,sha256=EmIxMO9WyN06fwsAGl7zlUJURa-9z4n3jWOA38ONfcw,35157
|
|
36
33
|
proximl/cli/project/__init__.py,sha256=ZSiXhsq7O1JwGecsBKBOD1W0VuiwErs-FFsfrXMOiFs,1918
|
|
37
34
|
proximl/cli/project/credential.py,sha256=5vPI6VBIo_YyvAzfUa9ARmz-LUnkdIVW0zbko9t0Q38,3443
|
|
38
35
|
proximl/cli/project/data_connector.py,sha256=CKF4snfrzDmeDXb4au8nV2W9jTweRMDZ89U2GAlBedQ,1411
|
|
@@ -57,15 +54,18 @@ proximl/projects/members.py,sha256=siREAa-Oac1pLGRHMXmj3ShoB0DVl8uY34eFdTlSezA,2
|
|
|
57
54
|
proximl/projects/projects.py,sha256=2lYStCIQ6_KB411NS_u1Ia2uatKxre1jFS6Lbr2LqzY,2840
|
|
58
55
|
proximl/projects/secrets.py,sha256=xlfzRONjT2ySJDcq8FYRQmSU2ZJMdPLS8NbePWYNCeM,2160
|
|
59
56
|
proximl/projects/services.py,sha256=aCESZjqfI9K-iXl8uJQsjEyoX29LuPaNv_TFjK6B2Ts,2771
|
|
57
|
+
proximl/utils/__init__.py,sha256=omDnxAdZ_MWqiK0cfcqPEp1EfRTHUCAC_kJYQa77K6M,39
|
|
58
|
+
proximl/utils/auth.py,sha256=K-JqDmifY83hVqGJvk1qlEEK8fb5KmVqpqQrEX9X-wA,26573
|
|
59
|
+
proximl/utils/transfer.py,sha256=EEQOUVbdu12P4gWcECuZYjozoi8lMcak9dVIz4guGqY,22395
|
|
60
60
|
tests/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
61
|
tests/integration/conftest.py,sha256=rqOKgDZ37SZH6CxXZIQSHtx8SF5GC1MlC49Zb5xrzsk,1135
|
|
62
|
-
tests/integration/test_checkpoints_integration.py,sha256=
|
|
63
|
-
tests/integration/test_datasets_integration.py,sha256=
|
|
62
|
+
tests/integration/test_checkpoints_integration.py,sha256=qHD-tzQc6QclqKf5o3pH2phcUps7K0PS3ctqPJls8M0,3219
|
|
63
|
+
tests/integration/test_datasets_integration.py,sha256=o1abXw5vvZ3RvKA-sQNBO3xJSDVgPaX-P4lNTeRnhWk,3518
|
|
64
64
|
tests/integration/test_environments_integration.py,sha256=7P6pKSyxA7rTwyNCD9HEaM2ablMG8WcBesOzkG-BgsQ,1403
|
|
65
65
|
tests/integration/test_gpu_types_integration.py,sha256=Zv-yrHcAgKau9BJQvzi92bdrRHhLPl_hbhhzNLEWJ9w,1256
|
|
66
|
-
tests/integration/test_jobs_integration.py,sha256=
|
|
67
|
-
tests/integration/test_models_integration.py,sha256=
|
|
68
|
-
tests/integration/test_volumes_integration.py,sha256=
|
|
66
|
+
tests/integration/test_jobs_integration.py,sha256=sX_DYopEW8mwKepMteyiaHoZMnd5Ct_ZKOjtU3uHZZw,25386
|
|
67
|
+
tests/integration/test_models_integration.py,sha256=2GY_RF_fvARIO67YS4qfAMfndk3NO8abcXMiEhvjH7g,2924
|
|
68
|
+
tests/integration/test_volumes_integration.py,sha256=ecgwQRc83glqHoRwohrDxvNHQ0XLFDwCFbVLWSN6C3M,3268
|
|
69
69
|
tests/integration/cloudbender/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
70
70
|
tests/integration/cloudbender/conftest.py,sha256=K1EQC7U7aBnywJq-QvBZINqHtQm7kq5feDWVKAtp22E,777
|
|
71
71
|
tests/integration/cloudbender/test_providers_integration.py,sha256=8_1TBxcIpQcET7VStHIsi_-_3j5hs8H-icsKN3qnNa8,1327
|
|
@@ -81,21 +81,21 @@ tests/integration/projects/test_projects_members_integration.py,sha256=4i4SeDCDZ
|
|
|
81
81
|
tests/integration/projects/test_projects_secrets_integration.py,sha256=TyqItJs-SBzOUwDy3vs_-yrDXeDF8r1_bAovr8C1a_s,1520
|
|
82
82
|
tests/integration/projects/test_projects_services_integration.py,sha256=cHOGSUpl3rqYJnCrbYp-2Zmn1ngFJTDV9Io7K8fDOp0,1569
|
|
83
83
|
tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
84
|
-
tests/unit/conftest.py,sha256=
|
|
85
|
-
tests/unit/test_auth_unit.py,sha256=
|
|
86
|
-
tests/unit/test_checkpoints_unit.py,sha256=
|
|
87
|
-
tests/unit/
|
|
88
|
-
tests/unit/test_datasets_unit.py,sha256=c3suBgQMtzJckHlY8MFwU38WundXobbjb-KXmUboulI,15910
|
|
84
|
+
tests/unit/conftest.py,sha256=LRrAR1KxlVDVuiSgS7krd12CxCaEXU4nG1fV2lUjjY0,35592
|
|
85
|
+
tests/unit/test_auth_unit.py,sha256=3oqdvz2jM-G37QM9FK6oCvS_w3EcVadz7rKawFqt-OU,1413
|
|
86
|
+
tests/unit/test_checkpoints_unit.py,sha256=OcPL61j9AqZWWPQsDxME5GQCud0xowkJuAB-__3OkB0,21914
|
|
87
|
+
tests/unit/test_datasets_unit.py,sha256=rv4qQoIjQaPCMPOGkH4T5sZyi5-cJlIDwtWr3OC0tK0,21135
|
|
89
88
|
tests/unit/test_environments_unit.py,sha256=HS4NN_cRWGQNDfovCxNGrVRoZI4NcUgsXyzvapNi6Ms,1882
|
|
90
|
-
tests/unit/test_exceptions.py,sha256=
|
|
91
|
-
tests/unit/test_gpu_types_unit.py,sha256=
|
|
92
|
-
tests/unit/test_jobs_unit.py,sha256=
|
|
93
|
-
tests/unit/
|
|
94
|
-
tests/unit/
|
|
95
|
-
tests/unit/
|
|
89
|
+
tests/unit/test_exceptions.py,sha256=qD6YV1wwAx-taCXSaBisc1w88-pKujJJPQykjebOIk8,5749
|
|
90
|
+
tests/unit/test_gpu_types_unit.py,sha256=eCPzi3EhKupDhlfIMPCIHCP3HXDM-KiheSsigxKJGIw,2526
|
|
91
|
+
tests/unit/test_jobs_unit.py,sha256=V_9xCupqQwcg_Cz3dtbZDsB9sknlgKJ-Hm6mElR_6zk,63964
|
|
92
|
+
tests/unit/test_main_unit.py,sha256=DSa7gE9D1ccxrPZCC0mUqWqTm7otC-OOGBfHaI_998I,627
|
|
93
|
+
tests/unit/test_models_unit.py,sha256=6YKMHHrAnhxU7RvVpqsf4elzcK8TOaQsuw0dscIUiu8,20127
|
|
94
|
+
tests/unit/test_proximl_unit.py,sha256=q0Sifg6uu8F_l5lUw6Sxifw-q5Y45eI7Bfk3A8o5WmA,23756
|
|
95
|
+
tests/unit/test_volumes_unit.py,sha256=2w3Nv7IqMMK3nXgmEN2LNNmt67hp2omeKNe1CB4_amo,20185
|
|
96
96
|
tests/unit/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
97
97
|
tests/unit/cli/conftest.py,sha256=w6p_2URicywJKUCtY79tSD_mx8cwJtxHbK_Lu3grOYs,236
|
|
98
|
-
tests/unit/cli/test_cli_checkpoint_unit.py,sha256=
|
|
98
|
+
tests/unit/cli/test_cli_checkpoint_unit.py,sha256=9-mtZxHb06b5QyyAXurcbOdRzdSfqBfUGkmZRiiKTgI,11830
|
|
99
99
|
tests/unit/cli/test_cli_datasets_unit.py,sha256=Hq9kWHMXIG2rI5GWjN-QuCquZ1D4Qaa62Bow0iPDOLk,653
|
|
100
100
|
tests/unit/cli/test_cli_environment_unit.py,sha256=iiNj_fxiCinq9FZgkwzcO_OLu9O279Hk8nJpFJwDpPg,683
|
|
101
101
|
tests/unit/cli/test_cli_gpu_unit.py,sha256=xdwIZEZJcJlWSuLBEcLhZXXH9EogZoKRiJlMRxaDa3o,650
|
|
@@ -121,21 +121,23 @@ tests/unit/cloudbender/test_data_connectors_unit.py,sha256=ZCnI9Gr2RAcpHiPZ5t2ka
|
|
|
121
121
|
tests/unit/cloudbender/test_datastores_unit.py,sha256=8PKa6XRdZ1MoVEwbRxA67qKeI6DrycpLU1RxWeokMnw,5281
|
|
122
122
|
tests/unit/cloudbender/test_device_configs_unit.py,sha256=wBDnTfrP6yl0K_jWcNU2ADR6iHoe1sRzMpvNfs_dwXs,5714
|
|
123
123
|
tests/unit/cloudbender/test_devices_unit.py,sha256=C2YTnfIpHlxdidgfbTnlzl72r5O7kqKStQUhWcTTXDg,9103
|
|
124
|
-
tests/unit/cloudbender/test_nodes_unit.py,sha256=
|
|
125
|
-
tests/unit/cloudbender/test_providers_unit.py,sha256=
|
|
126
|
-
tests/unit/cloudbender/test_regions_unit.py,sha256=
|
|
127
|
-
tests/unit/cloudbender/test_services_unit.py,sha256=
|
|
124
|
+
tests/unit/cloudbender/test_nodes_unit.py,sha256=qsiqAVDU_TaLStSBVwKJeK4Y1GzmNCTtGqeSYJJMtP0,10928
|
|
125
|
+
tests/unit/cloudbender/test_providers_unit.py,sha256=acCN_8sjmzg9Wc87Erd6M48-ngWhcsWziPMsIbRDeQM,8588
|
|
126
|
+
tests/unit/cloudbender/test_regions_unit.py,sha256=J_Qn_Vi-FQfMLqIy5T4MwEPUxjZW8Z2cDMpkX7esJSE,10961
|
|
127
|
+
tests/unit/cloudbender/test_services_unit.py,sha256=ZmFaleqzIeIXXDGAqYlochdoVMwgiHQDBg3vxRutc4Q,10956
|
|
128
128
|
tests/unit/projects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
129
129
|
tests/unit/projects/test_project_credentials_unit.py,sha256=y528DyvIm7uc5mFuwiUPjOMO1dkVcMEeYQqzMmKLOuk,3480
|
|
130
|
-
tests/unit/projects/test_project_data_connectors_unit.py,sha256=
|
|
131
|
-
tests/unit/projects/test_project_datastores_unit.py,sha256=
|
|
132
|
-
tests/unit/projects/test_project_members_unit.py,sha256=
|
|
130
|
+
tests/unit/projects/test_project_data_connectors_unit.py,sha256=C7IPXiZ6ZhAcgLFbjkkI8JDLt13DLI6eyZZFB1i3tGE,5004
|
|
131
|
+
tests/unit/projects/test_project_datastores_unit.py,sha256=9s_bzl2WrEyysyCaFI77kyY9h-wDGwRnvzHvKO4OiSk,4646
|
|
132
|
+
tests/unit/projects/test_project_members_unit.py,sha256=J9l1sS1U4Uj4zy89xP_3ZOjz5bEklLk4sWJ51H11H3E,5097
|
|
133
133
|
tests/unit/projects/test_project_secrets_unit.py,sha256=VE9L91FJodcwVGizfF65WYMiHZaF0s2AdW1aiJ3z7xA,3276
|
|
134
|
-
tests/unit/projects/test_project_services_unit.py,sha256=
|
|
135
|
-
tests/unit/projects/test_projects_unit.py,sha256=
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
proximl-0.
|
|
139
|
-
proximl-0.
|
|
140
|
-
proximl-0.
|
|
141
|
-
proximl-0.
|
|
134
|
+
tests/unit/projects/test_project_services_unit.py,sha256=8CHd6w2koDo7cwIba6_nGuHe5wCnCRv9Q8xsv_F9I7U,6140
|
|
135
|
+
tests/unit/projects/test_projects_unit.py,sha256=J6nXrigjMJONSfKpNzgWOUl0CrB3GYaLmcjnale5zvQ,4409
|
|
136
|
+
tests/unit/utils/__init__.py,sha256=VDy3m4Lfazpey8NMzHWdgcs3T9aaXWuH7pglIjCnZW0,38
|
|
137
|
+
tests/unit/utils/test_transfer_unit.py,sha256=hfPv-6sTnUlwrZdxTzciaF_huXOVkyX662UIGzmO994,188309
|
|
138
|
+
proximl-1.0.0.dist-info/LICENSE,sha256=ADFxLEZDxKY0j4MdyUd5GNuhQ18rnWH5rOz1ZG7yiOA,1069
|
|
139
|
+
proximl-1.0.0.dist-info/METADATA,sha256=9jMrrMKtP_j3VHdT6wukLnztZDDRHzou0NifyfaOz3Y,7287
|
|
140
|
+
proximl-1.0.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
141
|
+
proximl-1.0.0.dist-info/entry_points.txt,sha256=HmI311IIabkZReMCXu-nGbvIEW-KfaduAOyfiSqt5SY,63
|
|
142
|
+
proximl-1.0.0.dist-info/top_level.txt,sha256=-TWqc9tAaxmWmW4c7uYsmzPEYUIoh6z02xxqPbv7Kys,23
|
|
143
|
+
proximl-1.0.0.dist-info/RECORD,,
|
|
@@ -23,6 +23,7 @@ class GetCheckpointTests:
|
|
|
23
23
|
checkpoint = await checkpoint.wait_for("archived", 60)
|
|
24
24
|
|
|
25
25
|
async def test_get_checkpoints(self, proximl, checkpoint):
|
|
26
|
+
_ = checkpoint
|
|
26
27
|
checkpoints = await proximl.checkpoints.list()
|
|
27
28
|
assert len(checkpoints) > 0
|
|
28
29
|
|
|
@@ -55,7 +56,7 @@ class GetCheckpointTests:
|
|
|
55
56
|
|
|
56
57
|
@mark.create
|
|
57
58
|
@mark.asyncio
|
|
58
|
-
async def test_checkpoint_wasabi(proximl
|
|
59
|
+
async def test_checkpoint_wasabi(proximl):
|
|
59
60
|
checkpoint = await proximl.checkpoints.create(
|
|
60
61
|
name="CLI Automated Wasabi",
|
|
61
62
|
source_type="wasabi",
|
|
@@ -72,6 +73,7 @@ async def test_checkpoint_wasabi(proximl, capsys):
|
|
|
72
73
|
|
|
73
74
|
@mark.create
|
|
74
75
|
@mark.asyncio
|
|
76
|
+
@mark.local
|
|
75
77
|
async def test_checkpoint_local(proximl, capsys):
|
|
76
78
|
checkpoint = await proximl.checkpoints.create(
|
|
77
79
|
name="CLI Automated Local",
|
|
@@ -81,7 +83,6 @@ async def test_checkpoint_local(proximl, capsys):
|
|
|
81
83
|
attach_task = asyncio.create_task(checkpoint.attach())
|
|
82
84
|
connect_task = asyncio.create_task(checkpoint.connect())
|
|
83
85
|
await asyncio.gather(attach_task, connect_task)
|
|
84
|
-
await checkpoint.disconnect()
|
|
85
86
|
await checkpoint.refresh()
|
|
86
87
|
status = checkpoint.status
|
|
87
88
|
size = checkpoint.size
|
|
@@ -92,5 +93,5 @@ async def test_checkpoint_local(proximl, capsys):
|
|
|
92
93
|
sys.stdout.write(captured.out)
|
|
93
94
|
sys.stderr.write(captured.err)
|
|
94
95
|
assert "Starting data upload from local" in captured.out
|
|
95
|
-
assert "official/LICENSE
|
|
96
|
+
assert "official/LICENSE" in captured.out
|
|
96
97
|
assert "Upload complete" in captured.out
|
|
@@ -50,7 +50,9 @@ class GetDatasetTests:
|
|
|
50
50
|
async def test_dataset_repr(self, dataset):
|
|
51
51
|
string = repr(dataset)
|
|
52
52
|
regex = (
|
|
53
|
-
r"^Dataset\( proximl , \*\*{.*'dataset_uuid': '"
|
|
53
|
+
r"^Dataset\( proximl , \*\*{.*'dataset_uuid': '"
|
|
54
|
+
+ dataset.id
|
|
55
|
+
+ r"'.*}\)$"
|
|
54
56
|
)
|
|
55
57
|
assert isinstance(string, str)
|
|
56
58
|
assert re.match(regex, string)
|
|
@@ -79,6 +81,7 @@ class GetDatasetTests:
|
|
|
79
81
|
|
|
80
82
|
@mark.create
|
|
81
83
|
@mark.asyncio
|
|
84
|
+
@mark.local
|
|
82
85
|
async def test_dataset_local(proximl, capsys):
|
|
83
86
|
dataset = await proximl.datasets.create(
|
|
84
87
|
name="CLI Automated Local",
|
|
@@ -88,7 +91,6 @@ async def test_dataset_local(proximl, capsys):
|
|
|
88
91
|
attach_task = asyncio.create_task(dataset.attach())
|
|
89
92
|
connect_task = asyncio.create_task(dataset.connect())
|
|
90
93
|
await asyncio.gather(attach_task, connect_task)
|
|
91
|
-
await dataset.disconnect()
|
|
92
94
|
await dataset.refresh()
|
|
93
95
|
status = dataset.status
|
|
94
96
|
size = dataset.size
|
|
@@ -99,5 +101,5 @@ async def test_dataset_local(proximl, capsys):
|
|
|
99
101
|
sys.stdout.write(captured.out)
|
|
100
102
|
sys.stderr.write(captured.err)
|
|
101
103
|
assert "Starting data upload from local" in captured.out
|
|
102
|
-
assert "data_batch_1.bin
|
|
104
|
+
assert "data_batch_1.bin" in captured.out
|
|
103
105
|
assert "Upload complete" in captured.out
|
|
@@ -46,7 +46,10 @@ class JobLifeCycleTests:
|
|
|
46
46
|
job = await job.wait_for("running")
|
|
47
47
|
assert job.status == "running"
|
|
48
48
|
assert job.url
|
|
49
|
-
assert
|
|
49
|
+
assert (
|
|
50
|
+
extract_domain_suffix(urlparse(job.url).hostname)
|
|
51
|
+
== "proximl.cloud"
|
|
52
|
+
)
|
|
50
53
|
|
|
51
54
|
async def test_stop_job(self, job):
|
|
52
55
|
assert job.status == "running"
|
|
@@ -204,7 +207,8 @@ class JobAPIResourceValidationTests:
|
|
|
204
207
|
disk_size=10,
|
|
205
208
|
)
|
|
206
209
|
assert (
|
|
207
|
-
"Invalid Request - CPU Count must be a multiple of 4"
|
|
210
|
+
"Invalid Request - CPU Count must be a multiple of 4"
|
|
211
|
+
in error.value.message
|
|
208
212
|
)
|
|
209
213
|
|
|
210
214
|
async def test_invalid_gpu_count_for_cpu(self, proximl):
|
|
@@ -417,6 +421,7 @@ class JobAPIWorkerValidationTests:
|
|
|
417
421
|
@mark.asyncio
|
|
418
422
|
@mark.xdist_group("job_io")
|
|
419
423
|
class JobIOTests:
|
|
424
|
+
@mark.local
|
|
420
425
|
async def test_job_local_output(self, proximl, capsys):
|
|
421
426
|
temp_dir = tempfile.TemporaryDirectory()
|
|
422
427
|
job = await proximl.jobs.create(
|
|
@@ -426,7 +431,7 @@ class JobIOTests:
|
|
|
426
431
|
disk_size=10,
|
|
427
432
|
workers=["python $ML_MODEL_PATH/tensorflow/main.py"],
|
|
428
433
|
environment=dict(
|
|
429
|
-
type="
|
|
434
|
+
type="DEEPLEARNING_PY313",
|
|
430
435
|
env=[
|
|
431
436
|
dict(
|
|
432
437
|
key="CHECKPOINT_FILE",
|
|
@@ -452,13 +457,13 @@ class JobIOTests:
|
|
|
452
457
|
],
|
|
453
458
|
),
|
|
454
459
|
)
|
|
455
|
-
|
|
460
|
+
# Wait for job to reach running status since only output_type is local
|
|
461
|
+
await job.wait_for("running")
|
|
456
462
|
attach_task = asyncio.create_task(job.attach())
|
|
457
463
|
connect_task = asyncio.create_task(job.connect())
|
|
458
464
|
await asyncio.gather(attach_task, connect_task)
|
|
459
465
|
await job.refresh()
|
|
460
466
|
assert job.status == "finished"
|
|
461
|
-
await job.disconnect()
|
|
462
467
|
await job.remove()
|
|
463
468
|
upload_contents = os.listdir(temp_dir.name)
|
|
464
469
|
temp_dir.cleanup()
|
|
@@ -470,9 +475,8 @@ class JobIOTests:
|
|
|
470
475
|
captured = capsys.readouterr()
|
|
471
476
|
sys.stdout.write(captured.out)
|
|
472
477
|
sys.stderr.write(captured.err)
|
|
473
|
-
assert "Epoch 1/2" in captured.out
|
|
474
|
-
assert "
|
|
475
|
-
assert "adding: model.ckpt-0001" in captured.out
|
|
478
|
+
assert "Epoch 1/2" in captured.out or "Epoch 2/2" in captured.out
|
|
479
|
+
assert "model.ckpt-0001" in captured.out
|
|
476
480
|
assert "Send complete" in captured.out
|
|
477
481
|
|
|
478
482
|
async def test_job_model_input_and_output(self, proximl, capsys):
|
|
@@ -513,8 +517,7 @@ class JobIOTests:
|
|
|
513
517
|
captured = capsys.readouterr()
|
|
514
518
|
sys.stdout.write(captured.out)
|
|
515
519
|
sys.stderr.write(captured.err)
|
|
516
|
-
assert "Epoch 1/2" in captured.out
|
|
517
|
-
assert "Epoch 2/2" in captured.out
|
|
520
|
+
assert "Epoch 1/2" in captured.out or "Epoch 2/2" in captured.out
|
|
518
521
|
|
|
519
522
|
new_model = await proximl.models.get(workers[0].get("output_uuid"))
|
|
520
523
|
assert new_model.id
|
|
@@ -560,9 +563,12 @@ class JobTypeTests:
|
|
|
560
563
|
await job.wait_for("running")
|
|
561
564
|
await job.refresh()
|
|
562
565
|
assert job.url
|
|
563
|
-
assert
|
|
566
|
+
assert (
|
|
567
|
+
extract_domain_suffix(urlparse(job.url).hostname)
|
|
568
|
+
== "proximl.cloud"
|
|
569
|
+
)
|
|
564
570
|
tries = 0
|
|
565
|
-
await asyncio.sleep(180)
|
|
571
|
+
await asyncio.sleep(180) ## downloading weights can be slow
|
|
566
572
|
async with aiohttp.ClientSession() as session:
|
|
567
573
|
retry = True
|
|
568
574
|
while retry:
|
|
@@ -640,9 +646,11 @@ class JobTypeTests:
|
|
|
640
646
|
captured = capsys.readouterr()
|
|
641
647
|
sys.stdout.write(captured.out)
|
|
642
648
|
sys.stderr.write(captured.err)
|
|
643
|
-
assert "Epoch 1/2" in captured.out
|
|
644
|
-
assert
|
|
645
|
-
|
|
649
|
+
assert "Epoch 1/2" in captured.out or "Epoch 2/2" in captured.out
|
|
650
|
+
assert (
|
|
651
|
+
"Uploading s3://proximl-example/output/resnet_cifar10"
|
|
652
|
+
in captured.out
|
|
653
|
+
)
|
|
646
654
|
assert (
|
|
647
655
|
"upload: ./model.ckpt-0002.weights.h5 to s3://proximl-example/output/resnet_cifar10/model.ckpt-0002.weights.h5"
|
|
648
656
|
in captured.out
|
|
@@ -680,9 +688,12 @@ class JobFeatureTests:
|
|
|
680
688
|
captured = capsys.readouterr()
|
|
681
689
|
sys.stdout.write(captured.out)
|
|
682
690
|
sys.stderr.write(captured.err)
|
|
683
|
-
assert
|
|
684
|
-
|
|
691
|
+
assert (
|
|
692
|
+
"Train Epoch: 1 [0/60000 (0%)]" in captured.out
|
|
693
|
+
or "Train Epoch: 1 [59520/60000 (99%)]" in captured.out
|
|
694
|
+
)
|
|
685
695
|
|
|
696
|
+
@mark.local
|
|
686
697
|
async def test_inference_job(self, proximl, capsys):
|
|
687
698
|
temp_dir = tempfile.TemporaryDirectory()
|
|
688
699
|
job = await proximl.jobs.create(
|
|
@@ -706,11 +717,11 @@ class JobFeatureTests:
|
|
|
706
717
|
)
|
|
707
718
|
assert job.id
|
|
708
719
|
await job.wait_for("running")
|
|
709
|
-
|
|
710
|
-
|
|
720
|
+
attach_task = asyncio.create_task(job.attach())
|
|
721
|
+
connect_task = asyncio.create_task(job.connect())
|
|
722
|
+
await asyncio.gather(attach_task, connect_task)
|
|
711
723
|
await job.refresh()
|
|
712
724
|
assert job.status == "finished"
|
|
713
|
-
await job.disconnect()
|
|
714
725
|
await job.remove()
|
|
715
726
|
await job.wait_for("archived")
|
|
716
727
|
captured = capsys.readouterr()
|
|
@@ -719,15 +730,10 @@ class JobFeatureTests:
|
|
|
719
730
|
upload_contents = os.listdir(temp_dir.name)
|
|
720
731
|
temp_dir.cleanup()
|
|
721
732
|
assert len(upload_contents) >= 3
|
|
722
|
-
assert any(
|
|
723
|
-
"model.ckpt-0002" in content
|
|
724
|
-
for content in upload_contents
|
|
725
|
-
)
|
|
733
|
+
assert any("model.ckpt-0002" in content for content in upload_contents)
|
|
726
734
|
|
|
727
735
|
captured = capsys.readouterr()
|
|
728
736
|
sys.stdout.write(captured.out)
|
|
729
737
|
sys.stderr.write(captured.err)
|
|
730
|
-
assert "Epoch 1/2" in captured.out
|
|
731
|
-
assert "Epoch 2/2" in captured.out
|
|
732
|
-
assert "Number of regular files transferred: 4" in captured.out
|
|
738
|
+
assert "Epoch 1/2" in captured.out or "Epoch 2/2" in captured.out
|
|
733
739
|
assert "Send complete" in captured.out
|
|
@@ -44,7 +44,11 @@ class GetModelTests:
|
|
|
44
44
|
|
|
45
45
|
async def test_model_repr(self, model):
|
|
46
46
|
string = repr(model)
|
|
47
|
-
regex =
|
|
47
|
+
regex = (
|
|
48
|
+
r"^Model\( proximl , \*\*{.*'model_uuid': '"
|
|
49
|
+
+ model.id
|
|
50
|
+
+ r"'.*}\)$"
|
|
51
|
+
)
|
|
48
52
|
assert isinstance(string, str)
|
|
49
53
|
assert re.match(regex, string)
|
|
50
54
|
|
|
@@ -68,6 +72,7 @@ async def test_model_wasabi(proximl, capsys):
|
|
|
68
72
|
|
|
69
73
|
@mark.create
|
|
70
74
|
@mark.asyncio
|
|
75
|
+
@mark.local
|
|
71
76
|
async def test_model_local(proximl, capsys):
|
|
72
77
|
model = await proximl.models.create(
|
|
73
78
|
name="CLI Automated Local",
|
|
@@ -77,7 +82,6 @@ async def test_model_local(proximl, capsys):
|
|
|
77
82
|
attach_task = asyncio.create_task(model.attach())
|
|
78
83
|
connect_task = asyncio.create_task(model.connect())
|
|
79
84
|
await asyncio.gather(attach_task, connect_task)
|
|
80
|
-
await model.disconnect()
|
|
81
85
|
await model.refresh()
|
|
82
86
|
status = model.status
|
|
83
87
|
size = model.size
|
|
@@ -88,5 +92,5 @@ async def test_model_local(proximl, capsys):
|
|
|
88
92
|
sys.stdout.write(captured.out)
|
|
89
93
|
sys.stderr.write(captured.err)
|
|
90
94
|
assert "Starting data upload from local" in captured.out
|
|
91
|
-
assert "official/LICENSE
|
|
95
|
+
assert "official/LICENSE" in captured.out
|
|
92
96
|
assert "Upload complete" in captured.out
|
|
@@ -74,6 +74,7 @@ async def test_volume_wasabi(proximl, capsys):
|
|
|
74
74
|
|
|
75
75
|
@mark.create
|
|
76
76
|
@mark.asyncio
|
|
77
|
+
@mark.local
|
|
77
78
|
async def test_volume_local(proximl, capsys):
|
|
78
79
|
volume = await proximl.volumes.create(
|
|
79
80
|
name="CLI Automated Local",
|
|
@@ -84,7 +85,6 @@ async def test_volume_local(proximl, capsys):
|
|
|
84
85
|
attach_task = asyncio.create_task(volume.attach())
|
|
85
86
|
connect_task = asyncio.create_task(volume.connect())
|
|
86
87
|
await asyncio.gather(attach_task, connect_task)
|
|
87
|
-
await volume.disconnect()
|
|
88
88
|
await volume.refresh()
|
|
89
89
|
status = volume.status
|
|
90
90
|
billed_size = volume.billed_size
|
|
@@ -97,5 +97,5 @@ async def test_volume_local(proximl, capsys):
|
|
|
97
97
|
sys.stdout.write(captured.out)
|
|
98
98
|
sys.stderr.write(captured.err)
|
|
99
99
|
assert "Starting data upload from local" in captured.out
|
|
100
|
-
assert "official/LICENSE
|
|
100
|
+
assert "official/LICENSE" in captured.out
|
|
101
101
|
assert "Upload complete" in captured.out
|