proximl 0.5.13__py3-none-any.whl → 0.5.14__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.
@@ -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()
@@ -0,0 +1,49 @@
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 ProjectMembersTests:
12
+ @fixture(scope="class")
13
+ async def project_member(self, project):
14
+ member = await project.members.add("test.account@proximl.ai","read","read","read","read","read")
15
+ yield member
16
+ await project.members.remove("test.account@proximl.ai")
17
+
18
+ async def test_list_project_members(self, project):
19
+ members = await project.members.list()
20
+ assert len(members) > 0
21
+
22
+ async def test_project_member_properties(self, project, project_member):
23
+ assert isinstance(project_member.id, str)
24
+ assert isinstance(project_member.email, str)
25
+ assert isinstance(project_member.project_uuid, str)
26
+ assert isinstance(project_member.owner, bool)
27
+ assert isinstance(project_member.job, str)
28
+ assert isinstance(project_member.dataset, str)
29
+ assert isinstance(project_member.model, str)
30
+ assert isinstance(project_member.checkpoint, str)
31
+ assert isinstance(project_member.volume, str)
32
+ assert project.id == project_member.project_uuid
33
+ assert project_member.id == "test.account@proximl.ai"
34
+
35
+ async def test_project_member_str(self, project_member):
36
+ string = str(project_member)
37
+ regex = r"^{.*\"email\": \"" + project_member.email + r"\".*}$"
38
+ assert isinstance(string, str)
39
+ assert re.match(regex, string)
40
+
41
+ async def test_project_member_repr(self, project_member):
42
+ string = repr(project_member)
43
+ regex = (
44
+ r"^ProjectMember\( proximl , \*\*{.*'email': '"
45
+ + project_member.email
46
+ + r"'.*}\)$"
47
+ )
48
+ assert isinstance(string, str)
49
+ assert re.match(regex, string)
@@ -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
 
@@ -423,11 +423,11 @@ class JobIOTests:
423
423
  disk_size=10,
424
424
  workers=["python $ML_MODEL_PATH/tensorflow/main.py"],
425
425
  environment=dict(
426
- type="DEEPLEARNING_PY310",
426
+ type="DEEPLEARNING_PY312",
427
427
  env=[
428
428
  dict(
429
429
  key="CHECKPOINT_FILE",
430
- value="model.ckpt-0050",
430
+ value="model.ckpt-0050.weights.h5",
431
431
  )
432
432
  ],
433
433
  ),
@@ -469,7 +469,7 @@ class JobIOTests:
469
469
  sys.stderr.write(captured.err)
470
470
  assert "Epoch 1/2" in captured.out
471
471
  assert "Epoch 2/2" in captured.out
472
- assert "adding: model.ckpt-0001.data-00000-of-00001" in captured.out
472
+ assert "adding: model.ckpt-0001" in captured.out
473
473
  assert "Send complete" in captured.out
474
474
 
475
475
  async def test_job_model_input_and_output(self, proximl, capsys):
@@ -558,7 +558,7 @@ class JobTypeTests:
558
558
  assert job.url
559
559
  assert extract_domain_suffix(urlparse(job.url).hostname) == "proximl.cloud"
560
560
  tries = 0
561
- await asyncio.sleep(30)
561
+ await asyncio.sleep(180) ## downloading weights can be slow
562
562
  async with aiohttp.ClientSession() as session:
563
563
  retry = True
564
564
  while retry:
@@ -640,7 +640,7 @@ class JobTypeTests:
640
640
  assert "Epoch 2/2" in captured.out
641
641
  assert "Uploading s3://proximl-example/output/resnet_cifar10" in captured.out
642
642
  assert (
643
- "upload: ./model.ckpt-0002.data-00000-of-00001 to s3://proximl-example/output/resnet_cifar10/model.ckpt-0002.data-00000-of-00001"
643
+ "upload: ./model.ckpt-0002.weights.h5 to s3://proximl-example/output/resnet_cifar10/model.ckpt-0002.weights.h5"
644
644
  in captured.out
645
645
  )
646
646
  assert "Upload complete" in captured.out
@@ -713,9 +713,9 @@ class JobFeatureTests:
713
713
  sys.stderr.write(captured.err)
714
714
  upload_contents = os.listdir(temp_dir.name)
715
715
  temp_dir.cleanup()
716
- assert len(upload_contents) > 4
716
+ assert len(upload_contents) >= 3
717
717
  assert any(
718
- "model.ckpt-0002.data-00000-of-00001" in content
718
+ "model.ckpt-0002" in content
719
719
  for content in upload_contents
720
720
  )
721
721
 
@@ -724,5 +724,5 @@ class JobFeatureTests:
724
724
  sys.stderr.write(captured.err)
725
725
  assert "Epoch 1/2" in captured.out
726
726
  assert "Epoch 2/2" in captured.out
727
- assert "Number of regular files transferred: 7" in captured.out
727
+ assert "Number of regular files transferred: 4" in captured.out
728
728
  assert "Send complete" in captured.out
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
 
@@ -0,0 +1,107 @@
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.members 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_members(mock_proximl):
20
+ yield specimen.ProjectMembers(mock_proximl, project_id="1")
21
+
22
+
23
+ @fixture
24
+ def project_member(mock_proximl):
25
+ yield specimen.ProjectMember(
26
+ mock_proximl,
27
+ id="owner@gmail.com",
28
+ email="owner@gmail.com",
29
+ project_uuid="proj-id-1",
30
+ owner= True,
31
+ job= "all",
32
+ dataset= "all",
33
+ model= "all",
34
+ checkpoint="all",
35
+ volume= "all"
36
+ )
37
+
38
+
39
+ class ProjectMembersTests:
40
+ @mark.asyncio
41
+ async def test_project_members_list(self, project_members, mock_proximl):
42
+ api_response = [
43
+ {
44
+ "project_uuid": "proj-id-1",
45
+ "email": "owner@gmail.com",
46
+ "createdAt": "2024-09-04T00:42:39.529Z",
47
+ "updatedAt": "2024-09-04T00:42:39.529Z",
48
+ "owner": True,
49
+ "job": "all",
50
+ "dataset": "all",
51
+ "model": "all",
52
+ "checkpoint": "all",
53
+ "volume": "all"
54
+ },
55
+ {
56
+ "project_uuid": "proj-id-1",
57
+ "email": "non-owner@gmail.com",
58
+ "createdAt": "2024-09-04T00:42:39.529Z",
59
+ "updatedAt": "2024-09-04T00:42:39.529Z",
60
+ "owner": False,
61
+ "job": "all",
62
+ "dataset": "all",
63
+ "model": "all",
64
+ "checkpoint": "read",
65
+ "volume": "read"
66
+ },
67
+ ]
68
+ mock_proximl._query = AsyncMock(return_value=api_response)
69
+ resp = await project_members.list()
70
+ mock_proximl._query.assert_called_once_with(
71
+ "/project/1/access", "GET", dict()
72
+ )
73
+ assert len(resp) == 2
74
+
75
+
76
+ class ProjectMemberTests:
77
+ def test_project_member_properties(self, project_member):
78
+ assert isinstance(project_member.id, str)
79
+ assert isinstance(project_member.email, str)
80
+ assert isinstance(project_member.project_uuid, str)
81
+ assert isinstance(project_member.owner, bool)
82
+ assert isinstance(project_member.job, str)
83
+ assert isinstance(project_member.dataset, str)
84
+ assert isinstance(project_member.model, str)
85
+ assert isinstance(project_member.checkpoint, str)
86
+ assert isinstance(project_member.volume, str)
87
+
88
+ def test_project_member_str(self, project_member):
89
+ string = str(project_member)
90
+ regex = r"^{.*\"id\": \"" + project_member.id + r"\".*}$"
91
+ assert isinstance(string, str)
92
+ assert re.match(regex, string)
93
+
94
+ def test_project_member_repr(self, project_member):
95
+ string = repr(project_member)
96
+ regex = (
97
+ r"^ProjectMember\( proximl , \*\*{.*'id': '"
98
+ + project_member.id
99
+ + r"'.*}\)$"
100
+ )
101
+ assert isinstance(string, str)
102
+ assert re.match(regex, string)
103
+
104
+ def test_project_member_bool(self, project_member, mock_proximl):
105
+ empty_project_member = specimen.ProjectMember(mock_proximl)
106
+ assert bool(project_member)
107
+ assert not bool(empty_project_member)
@@ -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)