proximl 0.5.13__py3-none-any.whl → 0.5.13.post1__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.
proximl/__init__.py CHANGED
@@ -13,5 +13,5 @@ logging.basicConfig(
13
13
  logger = logging.getLogger(__name__)
14
14
 
15
15
 
16
- __version__ = "0.5.11"
16
+ __version__ = "0.5.13.post1"
17
17
  __all__ = "ProxiML"
proximl/cli/job/create.py CHANGED
@@ -172,12 +172,12 @@ def create(config):
172
172
  help="Conda packages to install as a comma separated list 'p1,\"p2=v2\",p3'",
173
173
  )
174
174
  @click.option(
175
- "--key",
175
+ "--credential",
176
176
  type=click.Choice(
177
177
  ["aws", "gcp", "kaggle", "azure", "wasabi"],
178
178
  case_sensitive=False,
179
179
  ),
180
- help="Third Party Keys to add to the job environment",
180
+ help="Third Party Credentials to add to the job environment",
181
181
  multiple=True,
182
182
  )
183
183
  @click.option(
@@ -221,7 +221,7 @@ def notebook(
221
221
  environment,
222
222
  custom_image,
223
223
  env,
224
- key,
224
+ credential,
225
225
  apt_packages,
226
226
  pip_packages,
227
227
  conda_packages,
@@ -254,7 +254,7 @@ def notebook(
254
254
  data=dict(datasets=datasets),
255
255
  model=dict(checkpoints=checkpoints),
256
256
  environment=dict(
257
- worker_key_types=[k for k in key],
257
+ credentials=[k for k in credential],
258
258
  ),
259
259
  )
260
260
 
@@ -500,12 +500,12 @@ def notebook(
500
500
  multiple=True,
501
501
  )
502
502
  @click.option(
503
- "--key",
503
+ "--credential",
504
504
  type=click.Choice(
505
505
  ["aws", "gcp", "kaggle", "azure", "wasabi"],
506
506
  case_sensitive=False,
507
507
  ),
508
- help="Third Party Keys to add to the job environment",
508
+ help="Third Party Credentials to add to the job environment",
509
509
  multiple=True,
510
510
  )
511
511
  @click.option(
@@ -563,7 +563,7 @@ def training(
563
563
  environment,
564
564
  custom_image,
565
565
  env,
566
- key,
566
+ credential,
567
567
  apt_packages,
568
568
  pip_packages,
569
569
  conda_packages,
@@ -596,7 +596,7 @@ def training(
596
596
  data=dict(datasets=datasets),
597
597
  model=dict(checkpoints=checkpoints),
598
598
  environment=dict(
599
- worker_key_types=[k for k in key],
599
+ credentials=[k for k in credential],
600
600
  ),
601
601
  )
602
602
 
@@ -844,12 +844,12 @@ def training(
844
844
  multiple=True,
845
845
  )
846
846
  @click.option(
847
- "--key",
847
+ "--credential",
848
848
  type=click.Choice(
849
849
  ["aws", "gcp", "kaggle", "azure", "wasabi"],
850
850
  case_sensitive=False,
851
851
  ),
852
- help="Third Party Keys to add to the job environment",
852
+ help="Third Party Credentials to add to the job environment",
853
853
  multiple=True,
854
854
  )
855
855
  @click.option(
@@ -907,7 +907,7 @@ def inference(
907
907
  environment,
908
908
  custom_image,
909
909
  env,
910
- key,
910
+ credential,
911
911
  apt_packages,
912
912
  pip_packages,
913
913
  conda_packages,
@@ -933,7 +933,7 @@ def inference(
933
933
  data=dict(datasets=[]),
934
934
  model=dict(checkpoints=checkpoints),
935
935
  environment=dict(
936
- worker_key_types=[k for k in key],
936
+ credentials=[k for k in credential],
937
937
  ),
938
938
  )
939
939
 
@@ -1163,12 +1163,12 @@ def from_json(config, attach, connect, file):
1163
1163
  multiple=True,
1164
1164
  )
1165
1165
  @click.option(
1166
- "--key",
1166
+ "--credential",
1167
1167
  type=click.Choice(
1168
1168
  ["aws", "gcp", "kaggle", "azure", "wasabi"],
1169
1169
  case_sensitive=False,
1170
1170
  ),
1171
- help="Third Party Keys to add to the job environment",
1171
+ help="Third Party Credentials to add to the job environment",
1172
1172
  multiple=True,
1173
1173
  )
1174
1174
  @click.option(
@@ -1230,7 +1230,7 @@ def endpoint(
1230
1230
  environment,
1231
1231
  custom_image,
1232
1232
  env,
1233
- key,
1233
+ credential,
1234
1234
  apt_packages,
1235
1235
  pip_packages,
1236
1236
  conda_packages,
@@ -1257,7 +1257,7 @@ def endpoint(
1257
1257
  max_price=max_price,
1258
1258
  model=dict(checkpoints=checkpoints),
1259
1259
  environment=dict(
1260
- worker_key_types=[k for k in key],
1260
+ credentials=[k for k in credential],
1261
1261
  ),
1262
1262
  )
1263
1263
 
@@ -78,7 +78,7 @@ def remove(config, project):
78
78
 
79
79
 
80
80
  from proximl.cli.project.secret import secret
81
- from proximl.cli.project.key import key
81
+ from proximl.cli.project.credential import credential
82
82
  from proximl.cli.project.data_connector import data_connector
83
83
  from proximl.cli.project.datastore import datastore
84
84
  from proximl.cli.project.service import service
@@ -1,4 +1,5 @@
1
1
  import click
2
+ import os
2
3
  from proximl.cli import pass_config
3
4
  from proximl.cli.project import project
4
5
 
@@ -42,17 +43,25 @@ def list(config):
42
43
 
43
44
 
44
45
  @secret.command()
46
+ @click.option(
47
+ "--file",
48
+ type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True),
49
+ help="Load the secret value from the file at the provided path",
50
+ )
45
51
  @click.argument("name", type=click.STRING)
46
52
  @pass_config
47
- def put(config, name):
53
+ def put(config, file, name):
48
54
  """
49
55
  Set a secret value.
50
56
 
51
57
  Secret is created with the specified NAME.
52
58
  """
53
59
  project = config.proximl.run(config.proximl.client.projects.get_current())
54
-
55
- value = click.prompt("Enter the secret value", type=str, hide_input=True)
60
+ if file:
61
+ with open(os.path.expanduser(file)) as f:
62
+ value = f.read()
63
+ else:
64
+ value = click.prompt("Enter the secret value", type=str, hide_input=True)
56
65
 
57
66
  return config.proximl.run(project.secrets.put(name=name, value=value))
58
67
 
@@ -7,6 +7,12 @@ class ProjectDataConnectors(object):
7
7
  self.proximl = proximl
8
8
  self.project_id = project_id
9
9
 
10
+ async def get(self, id, **kwargs):
11
+ resp = await self.proximl._query(
12
+ f"/project/{self.project_id}/data_connectors/{id}", "GET", kwargs
13
+ )
14
+ return ProjectDataConnector(self.proximl, **resp)
15
+
10
16
  async def list(self, **kwargs):
11
17
  resp = await self.proximl._query(
12
18
  f"/project/{self.project_id}/data_connectors", "GET", kwargs
@@ -61,3 +67,13 @@ class ProjectDataConnector:
61
67
 
62
68
  def __bool__(self):
63
69
  return bool(self._id)
70
+
71
+ async def enable(self):
72
+ await self.proximl._query(
73
+ f"/project/{self._project_uuid}/data_connectors/{self._id}/enable", "PATCH"
74
+ )
75
+
76
+ async def disable(self):
77
+ await self.proximl._query(
78
+ f"/project/{self._project_uuid}/data_connectors/{self._id}/disable", "PATCH"
79
+ )
@@ -7,6 +7,12 @@ class ProjectDatastores(object):
7
7
  self.proximl = proximl
8
8
  self.project_id = project_id
9
9
 
10
+ async def get(self, id, **kwargs):
11
+ resp = await self.proximl._query(
12
+ f"/project/{self.project_id}/datastores/{id}", "GET", kwargs
13
+ )
14
+ return ProjectDatastore(self.proximl, **resp)
15
+
10
16
  async def list(self, **kwargs):
11
17
  resp = await self.proximl._query(
12
18
  f"/project/{self.project_id}/datastores", "GET", kwargs
@@ -56,3 +62,13 @@ class ProjectDatastore:
56
62
 
57
63
  def __bool__(self):
58
64
  return bool(self._id)
65
+
66
+ async def enable(self):
67
+ await self.proximl._query(
68
+ f"/project/{self._project_uuid}/datastores/{self._id}/enable", "PATCH"
69
+ )
70
+
71
+ async def disable(self):
72
+ await self.proximl._query(
73
+ f"/project/{self._project_uuid}/datastores/{self._id}/disable", "PATCH"
74
+ )
@@ -3,7 +3,7 @@ import logging
3
3
  from .datastores import ProjectDatastores
4
4
  from .data_connectors import ProjectDataConnectors
5
5
  from .services import ProjectServices
6
- from .keys import ProjectKeys
6
+ from .credentials import ProjectCredentials
7
7
  from .secrets import ProjectSecrets
8
8
 
9
9
 
@@ -26,8 +26,11 @@ class Projects(object):
26
26
  projects = [Project(self.proximl, **project) for project in resp]
27
27
  return projects
28
28
 
29
- async def create(self, name, copy_keys=False, copy_secrets=False, **kwargs):
30
- data = dict(name=name, copy_keys=copy_keys, copy_secrets=copy_secrets)
29
+ async def create(self, name, copy_credentials=False, **kwargs):
30
+ data = dict(
31
+ name=name,
32
+ copy_credentials=copy_credentials,
33
+ )
31
34
  payload = {k: v for k, v in data.items() if v is not None}
32
35
  logging.info(f"Creating Project {name}")
33
36
  resp = await self.proximl._query("/project", "POST", None, payload)
@@ -51,7 +54,7 @@ class Project:
51
54
  self.datastores = ProjectDatastores(self.proximl, self._id)
52
55
  self.data_connectors = ProjectDataConnectors(self.proximl, self._id)
53
56
  self.services = ProjectServices(self.proximl, self._id)
54
- self.keys = ProjectKeys(self.proximl, self._id)
57
+ self.credentials = ProjectCredentials(self.proximl, self._id)
55
58
  self.secrets = ProjectSecrets(self.proximl, self._id)
56
59
 
57
60
  @property
@@ -24,7 +24,7 @@ class ProjectSecrets(object):
24
24
  f"/project/{self.project_id}/secret/{name}", "PUT", None, payload
25
25
  )
26
26
  secret = ProjectSecret(self.proximl, **resp)
27
- logging.info(f"Created Project Key {name} in project {self.project_id}")
27
+ logging.info(f"Created Project Secret {name} in project {self.project_id}")
28
28
  return secret
29
29
 
30
30
  async def remove(self, name, **kwargs):
@@ -7,6 +7,12 @@ class ProjectServices(object):
7
7
  self.proximl = proximl
8
8
  self.project_id = project_id
9
9
 
10
+ async def get(self, id, **kwargs):
11
+ resp = await self.proximl._query(
12
+ f"/project/{self.project_id}/services/{id}", "GET", kwargs
13
+ )
14
+ return ProjectService(self.proximl, **resp)
15
+
10
16
  async def list(self, **kwargs):
11
17
  resp = await self.proximl._query(
12
18
  f"/project/{self.project_id}/services", "GET", kwargs
@@ -61,3 +67,13 @@ class ProjectService:
61
67
 
62
68
  def __bool__(self):
63
69
  return bool(self._id)
70
+
71
+ async def enable(self):
72
+ await self.proximl._query(
73
+ f"/project/{self._project_uuid}/services/{self._id}/enable", "PATCH"
74
+ )
75
+
76
+ async def disable(self):
77
+ await self.proximl._query(
78
+ f"/project/{self._project_uuid}/services/{self._id}/disable", "PATCH"
79
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: proximl
3
- Version: 0.5.13
3
+ Version: 0.5.13.post1
4
4
  Summary: proxiML client SDK and command line utilities
5
5
  Home-page: https://github.com/proxiML/python-sdk
6
6
  Author: proxiML
@@ -2,7 +2,7 @@ examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  examples/create_dataset_and_training_job.py,sha256=Fqueoz2KD1MTxnU960iqHUdxvo68Xe64HT5XS55lI9w,1178
3
3
  examples/local_storage.py,sha256=6K6LMO7ZPI7N2KdBcgqXSvdsqJfjISzN4yRO9YrJqbA,1745
4
4
  examples/training_inference_pipeline.py,sha256=pxux0QUUtRXxKj2rX-6fPEKBIi43mhRd1zJ-Lf1ZJGI,2334
5
- proximl/__init__.py,sha256=V_dfFciJOujLG1RbQZrhWik3nYhzhU0V6c28qHJpOCk,433
5
+ proximl/__init__.py,sha256=H24uX4w44gBopXgz6-IQz2EmtKokV3dNMKqD9KEsAKM,439
6
6
  proximl/__main__.py,sha256=JgErYkiskih8Y6oRwowALtR-rwQhAAdqOYWjQraRIPI,59
7
7
  proximl/auth.py,sha256=LacGBDAVel5HcJx7JXp1wVn3s0gZc7nf--vDfSFOXYU,26565
8
8
  proximl/checkpoints.py,sha256=Ezpiab9Wfcmd2h5Slm9U5lekZGXiPzvhDKxXXgla1yo,8790
@@ -32,13 +32,12 @@ proximl/cli/cloudbender/provider.py,sha256=qhWbDK1tWi00wQWEYqGw7yGoZx0nEjV40GLHR
32
32
  proximl/cli/cloudbender/region.py,sha256=WnSkY4dXKRJ-FNaoxMfmoh6iuUx5dXCNJmEFT34Xtao,2892
33
33
  proximl/cli/cloudbender/service.py,sha256=6NuwlFULJLtOmMy9OFA8GkW4MLvNemAcd_KitQyDXV8,3147
34
34
  proximl/cli/job/__init__.py,sha256=s8mU2PvCWDcv4gGT3EmjHn8MIZlXBAoayoZKmnKpXnY,6545
35
- proximl/cli/job/create.py,sha256=sGvbenY0yxvxHo-FZVbdw8FaZx5D4ekTCjD7P4YHG4g,34288
36
- proximl/cli/project/__init__.py,sha256=nSU_qBNVPezVA_Uu54ha37PAfCmTsIclXptEvIwiRME,1904
35
+ proximl/cli/job/create.py,sha256=0EsICgLxP5EniWxN-eTKnJtMoKJJXcfgB5myfNzcDrs,34380
36
+ proximl/cli/project/__init__.py,sha256=ZSiXhsq7O1JwGecsBKBOD1W0VuiwErs-FFsfrXMOiFs,1918
37
37
  proximl/cli/project/credential.py,sha256=5vPI6VBIo_YyvAzfUa9ARmz-LUnkdIVW0zbko9t0Q38,3443
38
38
  proximl/cli/project/data_connector.py,sha256=CKF4snfrzDmeDXb4au8nV2W9jTweRMDZ89U2GAlBedQ,1411
39
39
  proximl/cli/project/datastore.py,sha256=YusrUTKY_qIwEOBN2gXOUoKCUp2qbWTKzquKc0DcUsE,1336
40
- proximl/cli/project/key.py,sha256=23ugcWOAxNJvC8VzG3FsEUWJ1_FZANnhq66cO04ZEVY,3203
41
- proximl/cli/project/secret.py,sha256=uys2FsXuO_8_EoolQNuOZ9btX4I0LXBeKG8dGx6StMM,1621
40
+ proximl/cli/project/secret.py,sha256=jWj9SNcx4jNKX1E84Fjkj0hRzF1XU0CrdYqNtxYuTpI,1927
42
41
  proximl/cli/project/service.py,sha256=06UoGbAWbPPh3kBdH3QXBTzj_k7AfKcD_bAyWGpYeDE,1310
43
42
  proximl/cloudbender/__init__.py,sha256=iE29obtC0_9f0IhRvHQcG5aY58fVhVYipTakpjAhdss,64
44
43
  proximl/cloudbender/cloudbender.py,sha256=k9Naj_le32YZotM7PRrhml3DxjqRetsHcgg5J4RtJ_4,717
@@ -52,34 +51,32 @@ proximl/cloudbender/regions.py,sha256=6doBdfMXIQI-uexzvwmNg2ATDzruatw-ixviZSMjon
52
51
  proximl/cloudbender/services.py,sha256=km3KcIgaRRVb3iuZEIn6ONIekuyXhBgk_brAFJcMMl4,5126
53
52
  proximl/projects/__init__.py,sha256=6NKCcHtQMeGB1IyU-djANphfnDX6MEkrXUM5Fyq9fWg,75
54
53
  proximl/projects/credentials.py,sha256=hWz6EUEAgltkAQMDjQVsFlVvfWUbZfY3KoWpldnCrXY,2255
55
- proximl/projects/data_connectors.py,sha256=559yJ-9qmva2JcNReuCyUQxdrSRIEROcGX5BDVr8ySs,1662
56
- proximl/projects/datastores.py,sha256=zAmKX9CibeS7PSXVvExk0SVrEo9Zq83kz6CQw0GoHck,1560
57
- proximl/projects/keys.py,sha256=yT5pgv1mGm50CaORf-HnsbDULad69G9I_QpVMN0zcuE,2157
58
- proximl/projects/projects.py,sha256=3aEGHxOMYbO9FaLSzSAA94A5ZGzljq-fBJk1QcSidCE,2755
59
- proximl/projects/secrets.py,sha256=NxjP1_CR9UQUMazeS-esin3zH54xZ4b4R11YNSU4hsI,2157
60
- proximl/projects/services.py,sha256=Jian2RHV9u3pHQKa7AsHKj25DrR4DstB-JaIDhSu7Tw,1679
54
+ proximl/projects/data_connectors.py,sha256=o2-K40BdF85TBXJgj1UMsznBmNHmnYh1qbZtHmmOa2Y,2216
55
+ proximl/projects/datastores.py,sha256=8nHpMEHn3UzsIhmPMoXympbRRJ10XkHdyRhBXUVXyeE,2095
56
+ proximl/projects/projects.py,sha256=V86mKR5USaLaqcKf7XcGIXeH5qmIL0bYITvnwqSTwzI,2792
57
+ proximl/projects/secrets.py,sha256=xlfzRONjT2ySJDcq8FYRQmSU2ZJMdPLS8NbePWYNCeM,2160
58
+ proximl/projects/services.py,sha256=C1YUxixkio8n4AlgmGqZJ93hP3VKOoTXVXTNCkRVd9Y,2206
61
59
  tests/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
60
  tests/integration/conftest.py,sha256=zRWpherX-yfbpk7xqZk9bIZCyJ-dwVeszY_7kekn2M4,1134
63
61
  tests/integration/test_checkpoints_integration.py,sha256=m-m6KM5Iy99bbCyA6VQVBFWc9MI7VItuoAPb_Q6Q0Fk,3206
64
62
  tests/integration/test_datasets_integration.py,sha256=Ndp8itnncDSjVH0t5BM5R_-_yL4qt6JrkQAVOTMi1R8,3499
65
63
  tests/integration/test_environments_integration.py,sha256=7P6pKSyxA7rTwyNCD9HEaM2ablMG8WcBesOzkG-BgsQ,1403
66
64
  tests/integration/test_gpu_types_integration.py,sha256=Zv-yrHcAgKau9BJQvzi92bdrRHhLPl_hbhhzNLEWJ9w,1256
67
- tests/integration/test_jobs_integration.py,sha256=pivsSH_wOgyf7X9KODmJR0kAQhY9RLFsRZ7RogCvaXc,25117
65
+ tests/integration/test_jobs_integration.py,sha256=9wY6ZfCv9FkafV0FJ5QRIwO0-8JR-81iB6uLT9C3pQ8,25110
68
66
  tests/integration/test_models_integration.py,sha256=cnsao7Zo4PwVCbdAdcBs0xombAslI_X_JOw6ipxdzOA,2878
69
67
  tests/integration/test_volumes_integration.py,sha256=Xo2Whw2U-7jyvESIkyex3f0SMXKlExe3kLmsbpXTHhQ,3270
70
68
  tests/integration/cloudbender/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
69
  tests/integration/cloudbender/test_providers_integration.py,sha256=gFqPQom-Cn1iZC50_ChQ2us2_f4tIPATQSAUcWdf7ss,1473
72
70
  tests/integration/projects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
- tests/integration/projects/conftest.py,sha256=o7rBOFGvcmZ3q0fy7jCIm2CBqn_ULojPP1XFBBUPEVQ,242
71
+ tests/integration/projects/conftest.py,sha256=4WbknSwdJgzPAr5qumCJD3Cl1rQFWgGZ5-Wro1ka0xA,249
74
72
  tests/integration/projects/test_projects_credentials_integration.py,sha256=_JqE2sGN09gZpvhtMRFjBPXumJ-PqKl8iXOgcYHlvSY,1636
75
73
  tests/integration/projects/test_projects_data_connectors_integration.py,sha256=ag6w2FFQYNlAdV83rOqat0FVZnP4JFhDunCvRwMJdzo,1630
76
74
  tests/integration/projects/test_projects_datastores_integration.py,sha256=DCHFnCYguhtrZvfTeWgKpPxlkeAXxVfE3IWkM4KjgAc,1469
77
75
  tests/integration/projects/test_projects_integration.py,sha256=wlRLxZkMnJZHlNPaeRFjAeyUlMfbgdrrFEI2eMBcoUI,1241
78
- tests/integration/projects/test_projects_keys_integration.py,sha256=cLvka_XlQHCYAFX4-gsH57KzhnpQZOGRvk9Q-HZEYbI,1423
79
- tests/integration/projects/test_projects_secrets_integration.py,sha256=Q8GEJkBE4X38F36sJza3VRo1pWdF9qEEr2kuADqgBB8,1478
76
+ tests/integration/projects/test_projects_secrets_integration.py,sha256=wRkcVkaf-zLWvCdJx9ikJYAoiJXU1esv0diRxwwRFdc,1481
80
77
  tests/integration/projects/test_projects_services_integration.py,sha256=MV9tZFTgrUtzImNrc-ZAoHYLbf_ZxAAAeVpxxr5AGdg,1530
81
78
  tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- tests/unit/conftest.py,sha256=VKpgpCDnWvDBqns7ENOe0eS_cCz_RIol5X3ybS4ePiQ,35521
79
+ tests/unit/conftest.py,sha256=11Z49O4mKXtm6xl18kWPomZvbZJQpqdaDYeJHFQbO1A,35588
83
80
  tests/unit/test_auth_unit.py,sha256=IJZHT5CZLNfu3MybTdEWIsKlvxNfFYpZ6oWYzbS856g,858
84
81
  tests/unit/test_checkpoints_unit.py,sha256=FbBM8Ffqy8JGTpWq2zWAWle2CI8A0MB_zABL_9Mezbk,15965
85
82
  tests/unit/test_connections_unit.py,sha256=LFAZzlrvL9oM8rZJTiC1oA9quw1KA2vMUCc3LV6SjXs,5507
@@ -111,7 +108,6 @@ tests/unit/cli/projects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
111
108
  tests/unit/cli/projects/test_cli_project_credential_unit.py,sha256=wehwquMGwUzwc8iH0bWletS3-kwIXKshoOuXHhJxRUc,943
112
109
  tests/unit/cli/projects/test_cli_project_data_connector_unit.py,sha256=RlqgHOUkFv3bmc19pUtGNVD0W1UWBJSDfaI_lzN0ZEA,993
113
110
  tests/unit/cli/projects/test_cli_project_datastore_unit.py,sha256=6UMgFwqxBtH65VeWTzXzaXhVfCRoG3Tef6aflqcDlV4,936
114
- tests/unit/cli/projects/test_cli_project_key_unit.py,sha256=Xb-O4cltVMNvHpSoPtIdfY4hmXUiMv-z5ixY49FKKyM,894
115
111
  tests/unit/cli/projects/test_cli_project_secret_unit.py,sha256=tygmgNOOf7C1J5Flo-YRo1-QLI0He5Yc_4Wx50ssC4o,915
116
112
  tests/unit/cli/projects/test_cli_project_service_unit.py,sha256=P-u_2-Gpbu0P_MjH6niAMDzj5M8oJYJ5adWcfU4LNpA,922
117
113
  tests/unit/cli/projects/test_cli_project_unit.py,sha256=64tR6ae-dQHVEE86N8tDrxOQypvyk8gANXGg6SBEUUI,627
@@ -128,13 +124,12 @@ tests/unit/projects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
128
124
  tests/unit/projects/test_project_credentials_unit.py,sha256=y528DyvIm7uc5mFuwiUPjOMO1dkVcMEeYQqzMmKLOuk,3480
129
125
  tests/unit/projects/test_project_data_connectors_unit.py,sha256=Yx2yCUgcuN_KfTKynZxse0Nx8jRrSlMygI7R8a-NjE4,3385
130
126
  tests/unit/projects/test_project_datastores_unit.py,sha256=WZMKkhpEg2dcevJqT7k6QRcYJF6FJfq177BDk2GWOBk,3129
131
- tests/unit/projects/test_project_keys_unit.py,sha256=n5Y2rKaenHA6JQFlViE1_dZ00FZ0PhM3C7rQtkuiRGM,3161
132
127
  tests/unit/projects/test_project_secrets_unit.py,sha256=VE9L91FJodcwVGizfF65WYMiHZaF0s2AdW1aiJ3z7xA,3276
133
128
  tests/unit/projects/test_project_services_unit.py,sha256=PzeNuJRuAG7RkrPWX0FfgFTt6-63FviecrDY06rLQ6A,3331
134
- tests/unit/projects/test_projects_unit.py,sha256=lTGdKOCN2bjzGORhaDVVlnzJBuEItUDGN36MsyQjDo4,3823
135
- proximl-0.5.13.dist-info/LICENSE,sha256=ADFxLEZDxKY0j4MdyUd5GNuhQ18rnWH5rOz1ZG7yiOA,1069
136
- proximl-0.5.13.dist-info/METADATA,sha256=jXM8TcsMbQr7eM5gZCwWm_hfxhGA3Y30v6el6LD0rn4,7345
137
- proximl-0.5.13.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
138
- proximl-0.5.13.dist-info/entry_points.txt,sha256=HmI311IIabkZReMCXu-nGbvIEW-KfaduAOyfiSqt5SY,63
139
- proximl-0.5.13.dist-info/top_level.txt,sha256=-TWqc9tAaxmWmW4c7uYsmzPEYUIoh6z02xxqPbv7Kys,23
140
- proximl-0.5.13.dist-info/RECORD,,
129
+ tests/unit/projects/test_projects_unit.py,sha256=4vMo7TF-SjduoT2ejpuyM3dULslpdqE8-c25M9X-iYc,3810
130
+ proximl-0.5.13.post1.dist-info/LICENSE,sha256=ADFxLEZDxKY0j4MdyUd5GNuhQ18rnWH5rOz1ZG7yiOA,1069
131
+ proximl-0.5.13.post1.dist-info/METADATA,sha256=BvyKWNRgTQNT4Wg2eqJeEwbjcsJWsPoANfYhJUVkfNU,7351
132
+ proximl-0.5.13.post1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
133
+ proximl-0.5.13.post1.dist-info/entry_points.txt,sha256=HmI311IIabkZReMCXu-nGbvIEW-KfaduAOyfiSqt5SY,63
134
+ proximl-0.5.13.post1.dist-info/top_level.txt,sha256=-TWqc9tAaxmWmW4c7uYsmzPEYUIoh6z02xxqPbv7Kys,23
135
+ proximl-0.5.13.post1.dist-info/RECORD,,
@@ -4,7 +4,7 @@ from pytest import fixture
4
4
  @fixture(scope="module")
5
5
  async def project(proximl):
6
6
  project = await proximl.projects.create(
7
- name="New Project", copy_keys=False, copy_secrets=False
7
+ name="New Project", copy_credentials=False, copy_secrets=False
8
8
  )
9
9
  yield project
10
10
  await project.remove()
@@ -17,7 +17,7 @@ class ProjectSecretsTests:
17
17
  yield project_secret
18
18
  await project.secrets.remove(name="secret_value")
19
19
 
20
- async def test_list_project_keys(self, project, project_secret):
20
+ async def test_list_project_secrets(self, project, project_secret):
21
21
  secrets = await project.secrets.list()
22
22
  assert len(secrets) > 0
23
23
 
@@ -175,7 +175,7 @@ class JobAPIResourceValidationTests:
175
175
  disk_size=10,
176
176
  )
177
177
  assert (
178
- "Invalid Request - None (CPU Only) may be not be combined with other GPU Types"
178
+ "Invalid Request - CPU Only may be not be combined with other GPU Types"
179
179
  in error.value.message
180
180
  )
181
181
 
tests/unit/conftest.py CHANGED
@@ -20,7 +20,7 @@ from proximl.projects import (
20
20
  from proximl.projects.datastores import ProjectDatastores, ProjectDatastore
21
21
  from proximl.projects.services import ProjectServices, ProjectService
22
22
  from proximl.projects.data_connectors import ProjectDataConnectors, ProjectDataConnector
23
- from proximl.projects.keys import ProjectKeys, ProjectKey
23
+ from proximl.projects.credentials import ProjectCredentials, ProjectCredential
24
24
  from proximl.projects.secrets import ProjectSecrets, ProjectSecret
25
25
 
26
26
  from proximl.cloudbender import Cloudbender
@@ -532,7 +532,7 @@ def mock_jobs():
532
532
  {"value": "env1val", "key": "env1"},
533
533
  {"value": "env2val", "key": "env2"},
534
534
  ],
535
- "worker_key_types": ["aws", "gcp"],
535
+ "credentials": ["aws", "gcp"],
536
536
  "status": "new",
537
537
  },
538
538
  "vpn": {
@@ -609,7 +609,7 @@ def mock_jobs():
609
609
  "type": "DEEPLEARNING_PY37",
610
610
  "image_size": 39656398629,
611
611
  "env": [],
612
- "worker_key_types": [],
612
+ "credentials": [],
613
613
  "status": "ready",
614
614
  },
615
615
  "vpn": {
@@ -1043,10 +1043,10 @@ def mock_device_configs():
1043
1043
  @fixture(
1044
1044
  scope="session",
1045
1045
  )
1046
- def mock_project_keys():
1046
+ def mock_project_credentials():
1047
1047
  proximl = Mock()
1048
1048
  yield [
1049
- ProjectKey(
1049
+ ProjectCredential(
1050
1050
  proximl,
1051
1051
  **{
1052
1052
  "project_uuid": "proj-id-1",
@@ -1055,7 +1055,7 @@ def mock_project_keys():
1055
1055
  "updatedAt": "2023-06-02T21:22:40.084Z",
1056
1056
  },
1057
1057
  ),
1058
- ProjectKey(
1058
+ ProjectCredential(
1059
1059
  proximl,
1060
1060
  **{
1061
1061
  "project_uuid": "proj-id-1",
@@ -1117,7 +1117,7 @@ def mock_proximl(
1117
1117
  mock_project_datastores,
1118
1118
  mock_project_services,
1119
1119
  mock_project_data_connectors,
1120
- mock_project_keys,
1120
+ mock_project_credentials,
1121
1121
  mock_project_secrets,
1122
1122
  ):
1123
1123
  proximl = create_autospec(ProxiML)
@@ -1150,8 +1150,8 @@ def mock_proximl(
1150
1150
  proximl.projects.data_connectors.list = AsyncMock(
1151
1151
  return_value=mock_project_data_connectors
1152
1152
  )
1153
- proximl.projects.keys = create_autospec(ProjectKeys)
1154
- proximl.projects.keys.list = AsyncMock(return_value=mock_project_keys)
1153
+ proximl.projects.credentials = create_autospec(ProjectCredentials)
1154
+ proximl.projects.credentials.list = AsyncMock(return_value=mock_project_credentials)
1155
1155
  proximl.projects.secrets = create_autospec(ProjectSecrets)
1156
1156
  proximl.projects.secrets.list = AsyncMock(return_value=mock_project_secrets)
1157
1157
 
@@ -75,7 +75,7 @@ class ProjectsTests:
75
75
  requested_config = dict(
76
76
  name="new project",
77
77
  )
78
- expected_payload = dict(name="new project", copy_keys=False, copy_secrets=False)
78
+ expected_payload = dict(name="new project", copy_credentials=False)
79
79
  api_response = {
80
80
  "id": "project-id-1",
81
81
  "name": "new project",
@@ -1,124 +0,0 @@
1
- import click
2
- import os
3
- import json
4
- import base64
5
- from pathlib import Path
6
- from proximl.cli import pass_config
7
- from proximl.cli.project import project
8
-
9
-
10
- @project.group()
11
- @pass_config
12
- def key(config):
13
- """proxiML project key commands."""
14
- pass
15
-
16
-
17
- @key.command()
18
- @pass_config
19
- def list(config):
20
- """List keys."""
21
- data = [
22
- ["TYPE", "KEY ID", "UPDATED AT"],
23
- [
24
- "-" * 80,
25
- "-" * 80,
26
- "-" * 80,
27
- ],
28
- ]
29
- project = config.proximl.run(config.proximl.client.projects.get_current())
30
- keys = config.proximl.run(project.keys.list())
31
-
32
- for key in keys:
33
- data.append(
34
- [
35
- key.type,
36
- key.key_id,
37
- key.updated_at.isoformat(timespec="seconds"),
38
- ]
39
- )
40
-
41
- for row in data:
42
- click.echo(
43
- "{: >13.11} {: >37.35} {: >28.26}" "".format(*row),
44
- file=config.stdout,
45
- )
46
-
47
-
48
- @key.command()
49
- @click.argument(
50
- "type",
51
- type=click.Choice(
52
- [
53
- "aws",
54
- "azure",
55
- "docker",
56
- "gcp",
57
- "huggingface",
58
- "kaggle",
59
- "ngc",
60
- "wasabi",
61
- ],
62
- case_sensitive=False,
63
- ),
64
- )
65
- @pass_config
66
- def put(config, type):
67
- """
68
- Set a key.
69
-
70
- A key is uploaded.
71
- """
72
- project = config.proximl.run(config.proximl.client.projects.get_current())
73
-
74
- tenant = None
75
-
76
- if type in ["aws", "wasabi"]:
77
- key_id = click.prompt("Enter the key ID", type=str, hide_input=False)
78
- secret = click.prompt("Enter the secret key", type=str, hide_input=True)
79
- elif type == "azure":
80
- key_id = click.prompt(
81
- "Enter the Application (client) ID", type=str, hide_input=False
82
- )
83
- tenant = click.prompt(
84
- "Enter the Directory (tenant) ley", type=str, hide_input=False
85
- )
86
- secret = click.prompt("Enter the client secret", type=str, hide_input=True)
87
- elif type in ["docker", "huggingface"]:
88
- key_id = click.prompt("Enter the username", type=str, hide_input=False)
89
- secret = click.prompt("Enter the access token", type=str, hide_input=True)
90
- elif type in ["gcp", "kaggle"]:
91
- file_name = click.prompt(
92
- "Enter the path of the credentials file",
93
- type=click.Path(
94
- exists=True, file_okay=True, dir_okay=False, resolve_path=True
95
- ),
96
- hide_input=False,
97
- )
98
- key_id = os.path.basename(file_name)
99
- with open(file_name) as f:
100
- secret = json.load(f)
101
- secret = json.dumps(secret)
102
- elif type == "ngc":
103
- key_id = "$oauthtoken"
104
- secret = click.prompt("Enter the access token", type=str, hide_input=True)
105
- else:
106
- raise click.UsageError("Unsupported key type")
107
-
108
- return config.proximl.run(
109
- project.keys.put(type=type, key_id=key_id, secret=secret, tenant=tenant)
110
- )
111
-
112
-
113
- @key.command()
114
- @click.argument("name", type=click.STRING)
115
- @pass_config
116
- def remove(config, name):
117
- """
118
- Remove a key.
119
-
120
-
121
- """
122
- project = config.proximl.run(config.proximl.client.projects.get_current())
123
-
124
- return config.proximl.run(project.key.remove(name))
proximl/projects/keys.py DELETED
@@ -1,71 +0,0 @@
1
- import json
2
- import logging
3
- from datetime import datetime
4
- from dateutil import parser, tz
5
-
6
-
7
- class ProjectKeys(object):
8
- def __init__(self, proximl, project_id):
9
- self.proximl = proximl
10
- self.project_id = project_id
11
-
12
- async def list(self, **kwargs):
13
- resp = await self.proximl._query(
14
- f"/project/{self.project_id}/keys", "GET", kwargs
15
- )
16
- keys = [ProjectKey(self.proximl, **service) for service in resp]
17
- return keys
18
-
19
- async def put(self, type, key_id, secret, tenant=None, **kwargs):
20
- data = dict(key_id=key_id, secret=secret, tenant=tenant)
21
- payload = {k: v for k, v in data.items() if v is not None}
22
- logging.info(f"Creating Project Key {type}")
23
- resp = await self.proximl._query(
24
- f"/project/{self.project_id}/key/{type}", "PUT", None, payload
25
- )
26
- key = ProjectKey(self.proximl, **resp)
27
- logging.info(f"Created Project Key {type} in project {self.project_id}")
28
-
29
- return key
30
-
31
- async def remove(self, type, **kwargs):
32
- await self.proximl._query(
33
- f"/project/{self.project_id}/key/{type}", "DELETE", kwargs
34
- )
35
-
36
-
37
- class ProjectKey:
38
- def __init__(self, proximl, **kwargs):
39
- self.proximl = proximl
40
- self._entity = kwargs
41
- self._type = self._entity.get("type")
42
- self._project_uuid = self._entity.get("project_uuid")
43
- self._key_id = self._entity.get("key_id")
44
- self._updated_at = self._entity.get("updatedAt")
45
-
46
- @property
47
- def type(self) -> str:
48
- return self._type
49
-
50
- @property
51
- def project_uuid(self) -> str:
52
- return self._project_uuid
53
-
54
- @property
55
- def key_id(self) -> str:
56
- return self._key_id
57
-
58
- @property
59
- def updated_at(self) -> datetime:
60
- timestamp = parser.isoparse(self._updated_at)
61
- timezone = tz.tzlocal()
62
- return timestamp.astimezone(timezone)
63
-
64
- def __str__(self):
65
- return json.dumps({k: v for k, v in self._entity.items()})
66
-
67
- def __repr__(self):
68
- return f"ProjectKey( proximl , **{self._entity.__repr__()})"
69
-
70
- def __bool__(self):
71
- return bool(self._type)
@@ -1,43 +0,0 @@
1
- import re
2
- import sys
3
- import asyncio
4
- from pytest import mark, fixture
5
-
6
- pytestmark = [mark.sdk, mark.integration, mark.projects]
7
-
8
-
9
- @mark.create
10
- @mark.asyncio
11
- class ProjectKeysTests:
12
- @fixture(scope="class")
13
- async def project_key(self, project):
14
- project_key = await project.keys.put(
15
- type="aws", key_id="ASFHALKF", secret="IUHKLHKAHF"
16
- )
17
- yield project_key
18
- await project.keys.remove(type="aws")
19
-
20
- async def test_list_project_keys(self, project, project_key):
21
- keys = await project.keys.list()
22
- assert len(keys) > 0
23
-
24
- async def test_project_key_properties(self, project, project_key):
25
- assert isinstance(project_key.project_uuid, str)
26
- assert isinstance(project_key.type, str)
27
- assert isinstance(project_key.key_id, str)
28
- assert project_key.type == "aws"
29
- assert project.id == project_key.project_uuid
30
-
31
- async def test_project_key_str(self, project_key):
32
- string = str(project_key)
33
- regex = r"^{.*\"type\": \"" + project_key.type + r"\".*}$"
34
- assert isinstance(string, str)
35
- assert re.match(regex, string)
36
-
37
- async def test_project_key_repr(self, project_key):
38
- string = repr(project_key)
39
- regex = (
40
- r"^ProjectKey\( proximl , \*\*{.*'type': '" + project_key.type + r"'.*}\)$"
41
- )
42
- assert isinstance(string, str)
43
- assert re.match(regex, string)
@@ -1,26 +0,0 @@
1
- import re
2
- import json
3
- import click
4
- from unittest.mock import AsyncMock, patch, create_autospec
5
- from pytest import mark, fixture, raises
6
-
7
- pytestmark = [mark.cli, mark.unit, mark.projects]
8
-
9
- from proximl.cli.project import key as specimen
10
- from proximl.projects import (
11
- Project,
12
- )
13
-
14
-
15
- def test_list_keys(runner, mock_project_keys):
16
- with patch("proximl.cli.ProxiML", new=AsyncMock) as mock_proximl:
17
- project = create_autospec(Project)
18
- mock_proximl.projects = AsyncMock()
19
- mock_proximl.projects.get = AsyncMock(return_value=project)
20
- mock_proximl.projects.get_current = AsyncMock(return_value=project)
21
- project.keys = AsyncMock()
22
- project.keys.list = AsyncMock(return_value=mock_project_keys)
23
- result = runner.invoke(specimen, ["list"])
24
- print(result)
25
- assert result.exit_code == 0
26
- project.keys.list.assert_called_once()
@@ -1,96 +0,0 @@
1
- import re
2
- import json
3
- import logging
4
- from unittest.mock import AsyncMock, patch
5
- from pytest import mark, fixture, raises
6
- from aiohttp import WSMessage, WSMsgType
7
-
8
- import proximl.projects.keys as specimen
9
- from proximl.exceptions import (
10
- ApiError,
11
- SpecificationError,
12
- ProxiMLException,
13
- )
14
-
15
- pytestmark = [mark.sdk, mark.unit, mark.projects]
16
-
17
-
18
- @fixture
19
- def project_keys(mock_proximl):
20
- yield specimen.ProjectKeys(mock_proximl, project_id="1")
21
-
22
-
23
- @fixture
24
- def project_key(mock_proximl):
25
- yield specimen.ProjectKey(
26
- mock_proximl, project_uuid="proj-id-1", type="aws", key_id="AIYHGFSDLK"
27
- )
28
-
29
-
30
- class ProjectKeysTests:
31
- @mark.asyncio
32
- async def test_project_keys_list(self, project_keys, mock_proximl):
33
- api_response = [
34
- {"project_uuid": "proj-id-1", "type": "aws", "key_id": "AIYHGFSDLK"},
35
- {"project_uuid": "proj-id-1", "type": "gcp", "key_id": "credentials.json"},
36
- ]
37
- mock_proximl._query = AsyncMock(return_value=api_response)
38
- resp = await project_keys.list()
39
- mock_proximl._query.assert_called_once_with("/project/1/keys", "GET", dict())
40
- assert len(resp) == 2
41
-
42
- @mark.asyncio
43
- async def test_remove_project_key(
44
- self,
45
- project_keys,
46
- mock_proximl,
47
- ):
48
- api_response = dict()
49
- mock_proximl._query = AsyncMock(return_value=api_response)
50
- await project_keys.remove("aws")
51
- mock_proximl._query.assert_called_once_with(
52
- "/project/1/key/aws", "DELETE", dict()
53
- )
54
-
55
- @mark.asyncio
56
- async def test_put_project_key(self, project_keys, mock_proximl):
57
- requested_config = dict(type="aws", key_id="AIUDHADA", secret="ASKHJSLKF")
58
- expected_payload = dict(key_id="AIUDHADA", secret="ASKHJSLKF")
59
- api_response = {
60
- "project_uuid": "project-id-1",
61
- "type": "aws",
62
- "key_id": "AIUDHADA",
63
- }
64
-
65
- mock_proximl._query = AsyncMock(return_value=api_response)
66
- response = await project_keys.put(**requested_config)
67
- mock_proximl._query.assert_called_once_with(
68
- "/project/1/key/aws", "PUT", None, expected_payload
69
- )
70
- assert response.type == "aws"
71
-
72
-
73
- class ProjectKeyTests:
74
- def test_project_key_properties(self, project_key):
75
- assert isinstance(project_key.type, str)
76
- assert isinstance(project_key.key_id, str)
77
- assert isinstance(project_key.project_uuid, str)
78
-
79
- def test_project_key_str(self, project_key):
80
- string = str(project_key)
81
- regex = r"^{.*\"type\": \"" + project_key.type + r"\".*}$"
82
- assert isinstance(string, str)
83
- assert re.match(regex, string)
84
-
85
- def test_project_key_repr(self, project_key):
86
- string = repr(project_key)
87
- regex = (
88
- r"^ProjectKey\( proximl , \*\*{.*'type': '" + project_key.type + r"'.*}\)$"
89
- )
90
- assert isinstance(string, str)
91
- assert re.match(regex, string)
92
-
93
- def test_project_key_bool(self, project_key, mock_proximl):
94
- empty_project_key = specimen.ProjectKey(mock_proximl)
95
- assert bool(project_key)
96
- assert not bool(empty_project_key)