trainml 0.5.8__py3-none-any.whl → 0.5.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. tests/integration/projects/__init__.py +0 -0
  2. tests/integration/projects/conftest.py +10 -0
  3. tests/integration/projects/test_projects_data_connectors_integration.py +44 -0
  4. tests/integration/projects/test_projects_datastores_integration.py +42 -0
  5. tests/integration/{test_projects_integration.py → projects/test_projects_integration.py} +0 -6
  6. tests/integration/projects/test_projects_keys_integration.py +43 -0
  7. tests/integration/projects/test_projects_secrets_integration.py +44 -0
  8. tests/integration/projects/test_projects_services_integration.py +44 -0
  9. tests/integration/test_checkpoints_integration.py +1 -2
  10. tests/integration/test_models_integration.py +0 -1
  11. tests/unit/cli/projects/__init__.py +0 -0
  12. tests/unit/cli/projects/test_cli_project_data_connector_unit.py +28 -0
  13. tests/unit/cli/projects/test_cli_project_datastore_unit.py +26 -0
  14. tests/unit/cli/projects/test_cli_project_key_unit.py +26 -0
  15. tests/unit/cli/projects/test_cli_project_secret_unit.py +26 -0
  16. tests/unit/cli/projects/test_cli_project_service_unit.py +26 -0
  17. tests/unit/cli/projects/test_cli_project_unit.py +19 -0
  18. tests/unit/cloudbender/test_datastores_unit.py +1 -5
  19. tests/unit/conftest.py +146 -3
  20. tests/unit/projects/__init__.py +0 -0
  21. tests/unit/projects/test_project_data_connectors_unit.py +102 -0
  22. tests/unit/projects/test_project_datastores_unit.py +96 -0
  23. tests/unit/projects/test_project_keys_unit.py +96 -0
  24. tests/unit/projects/test_project_secrets_unit.py +101 -0
  25. tests/unit/projects/test_project_services_unit.py +102 -0
  26. tests/unit/projects/test_projects_unit.py +128 -0
  27. tests/unit/test_checkpoints_unit.py +15 -23
  28. tests/unit/test_datasets_unit.py +15 -20
  29. tests/unit/test_models_unit.py +13 -16
  30. tests/unit/test_volumes_unit.py +3 -0
  31. trainml/__init__.py +1 -1
  32. trainml/checkpoints.py +14 -3
  33. trainml/cli/cloudbender/datastore.py +2 -7
  34. trainml/cli/project/__init__.py +84 -0
  35. trainml/cli/project/data_connector.py +61 -0
  36. trainml/cli/project/datastore.py +61 -0
  37. trainml/cli/project/key.py +124 -0
  38. trainml/cli/project/secret.py +71 -0
  39. trainml/cli/project/service.py +61 -0
  40. trainml/cloudbender/data_connectors.py +8 -0
  41. trainml/cloudbender/datastores.py +9 -19
  42. trainml/cloudbender/nodes.py +44 -1
  43. trainml/cloudbender/providers.py +53 -0
  44. trainml/cloudbender/regions.py +48 -0
  45. trainml/datasets.py +14 -3
  46. trainml/exceptions.py +51 -0
  47. trainml/jobs.py +2 -13
  48. trainml/models.py +14 -3
  49. trainml/projects/__init__.py +3 -0
  50. trainml/projects/data_connectors.py +63 -0
  51. trainml/projects/datastores.py +58 -0
  52. trainml/projects/keys.py +71 -0
  53. trainml/projects/projects.py +83 -0
  54. trainml/projects/secrets.py +70 -0
  55. trainml/projects/services.py +63 -0
  56. trainml/volumes.py +15 -3
  57. {trainml-0.5.8.dist-info → trainml-0.5.11.dist-info}/METADATA +1 -1
  58. {trainml-0.5.8.dist-info → trainml-0.5.11.dist-info}/RECORD +64 -38
  59. tests/unit/cli/cloudbender/test_cli_reservation_unit.py +0 -34
  60. tests/unit/cli/test_cli_project_unit.py +0 -42
  61. tests/unit/cloudbender/test_reservations_unit.py +0 -173
  62. tests/unit/test_projects_unit.py +0 -320
  63. trainml/cli/cloudbender/reservation.py +0 -159
  64. trainml/cli/project.py +0 -149
  65. trainml/cloudbender/reservations.py +0 -126
  66. trainml/projects.py +0 -228
  67. /tests/unit/{test_auth.py → test_auth_unit.py} +0 -0
  68. /tests/unit/{test_trainml.py → test_trainml_unit.py} +0 -0
  69. {trainml-0.5.8.dist-info → trainml-0.5.11.dist-info}/LICENSE +0 -0
  70. {trainml-0.5.8.dist-info → trainml-0.5.11.dist-info}/WHEEL +0 -0
  71. {trainml-0.5.8.dist-info → trainml-0.5.11.dist-info}/entry_points.txt +0 -0
  72. {trainml-0.5.8.dist-info → trainml-0.5.11.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,102 @@
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 trainml.projects.data_connectors as specimen
9
+ from trainml.exceptions import (
10
+ ApiError,
11
+ SpecificationError,
12
+ TrainMLException,
13
+ )
14
+
15
+ pytestmark = [mark.sdk, mark.unit, mark.projects]
16
+
17
+
18
+ @fixture
19
+ def project_data_connectors(mock_trainml):
20
+ yield specimen.ProjectDataConnectors(mock_trainml, project_id="1")
21
+
22
+
23
+ @fixture
24
+ def project_data_connector(mock_trainml):
25
+ yield specimen.ProjectDataConnector(
26
+ mock_trainml,
27
+ id="ds-id-1",
28
+ name="connector 1",
29
+ project_uuid="proj-id-1",
30
+ type="custom",
31
+ region_uuid="reg-id-1",
32
+ )
33
+
34
+
35
+ class ProjectDataConnectorsTests:
36
+ @mark.asyncio
37
+ async def test_project_data_connectors_refresh(
38
+ self, project_data_connectors, mock_trainml
39
+ ):
40
+ api_response = dict()
41
+ mock_trainml._query = AsyncMock(return_value=api_response)
42
+ await project_data_connectors.refresh()
43
+ mock_trainml._query.assert_called_once_with(
44
+ "/project/1/data_connectors", "PATCH"
45
+ )
46
+
47
+ @mark.asyncio
48
+ async def test_project_data_connectors_list(
49
+ self, project_data_connectors, mock_trainml
50
+ ):
51
+ api_response = [
52
+ {
53
+ "project_uuid": "proj-id-1",
54
+ "region_uuid": "reg-id-1",
55
+ "id": "store-id-1",
56
+ "type": "custom",
57
+ "name": "On-Prem Connection A",
58
+ },
59
+ {
60
+ "project_uuid": "proj-id-1",
61
+ "region_uuid": "reg-id-2",
62
+ "id": "store-id-2",
63
+ "type": "custom",
64
+ "name": "Cloud Connection B",
65
+ },
66
+ ]
67
+ mock_trainml._query = AsyncMock(return_value=api_response)
68
+ resp = await project_data_connectors.list()
69
+ mock_trainml._query.assert_called_once_with(
70
+ "/project/1/data_connectors", "GET", dict()
71
+ )
72
+ assert len(resp) == 2
73
+
74
+
75
+ class ProjectDataConnectorTests:
76
+ def test_project_data_connector_properties(self, project_data_connector):
77
+ assert isinstance(project_data_connector.id, str)
78
+ assert isinstance(project_data_connector.name, str)
79
+ assert isinstance(project_data_connector.project_uuid, str)
80
+ assert isinstance(project_data_connector.type, str)
81
+ assert isinstance(project_data_connector.region_uuid, str)
82
+
83
+ def test_project_data_connector_str(self, project_data_connector):
84
+ string = str(project_data_connector)
85
+ regex = r"^{.*\"id\": \"" + project_data_connector.id + r"\".*}$"
86
+ assert isinstance(string, str)
87
+ assert re.match(regex, string)
88
+
89
+ def test_project_data_connector_repr(self, project_data_connector):
90
+ string = repr(project_data_connector)
91
+ regex = (
92
+ r"^ProjectDataConnector\( trainml , \*\*{.*'id': '"
93
+ + project_data_connector.id
94
+ + r"'.*}\)$"
95
+ )
96
+ assert isinstance(string, str)
97
+ assert re.match(regex, string)
98
+
99
+ def test_project_data_connector_bool(self, project_data_connector, mock_trainml):
100
+ empty_project_data_connector = specimen.ProjectDataConnector(mock_trainml)
101
+ assert bool(project_data_connector)
102
+ assert not bool(empty_project_data_connector)
@@ -0,0 +1,96 @@
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 trainml.projects.datastores as specimen
9
+ from trainml.exceptions import (
10
+ ApiError,
11
+ SpecificationError,
12
+ TrainMLException,
13
+ )
14
+
15
+ pytestmark = [mark.sdk, mark.unit, mark.projects]
16
+
17
+
18
+ @fixture
19
+ def project_datastores(mock_trainml):
20
+ yield specimen.ProjectDatastores(mock_trainml, project_id="1")
21
+
22
+
23
+ @fixture
24
+ def project_datastore(mock_trainml):
25
+ yield specimen.ProjectDatastore(
26
+ mock_trainml,
27
+ id="ds-id-1",
28
+ name="datastore 1",
29
+ project_uuid="proj-id-1",
30
+ type="nfs",
31
+ region_uuid="reg-id-1",
32
+ )
33
+
34
+
35
+ class ProjectDatastoresTests:
36
+ @mark.asyncio
37
+ async def test_project_datastores_refresh(self, project_datastores, mock_trainml):
38
+ api_response = dict()
39
+ mock_trainml._query = AsyncMock(return_value=api_response)
40
+ await project_datastores.refresh()
41
+ mock_trainml._query.assert_called_once_with("/project/1/datastores", "PATCH")
42
+
43
+ @mark.asyncio
44
+ async def test_project_datastores_list(self, project_datastores, mock_trainml):
45
+ api_response = [
46
+ {
47
+ "project_uuid": "proj-id-1",
48
+ "region_uuid": "reg-id-1",
49
+ "id": "store-id-1",
50
+ "type": "nfs",
51
+ "name": "On-prem NFS",
52
+ },
53
+ {
54
+ "project_uuid": "proj-id-1",
55
+ "region_uuid": "reg-id-2",
56
+ "id": "store-id-2",
57
+ "type": "smb",
58
+ "name": "GCP Samba",
59
+ },
60
+ ]
61
+ mock_trainml._query = AsyncMock(return_value=api_response)
62
+ resp = await project_datastores.list()
63
+ mock_trainml._query.assert_called_once_with(
64
+ "/project/1/datastores", "GET", dict()
65
+ )
66
+ assert len(resp) == 2
67
+
68
+
69
+ class ProjectDatastoreTests:
70
+ def test_project_datastore_properties(self, project_datastore):
71
+ assert isinstance(project_datastore.id, str)
72
+ assert isinstance(project_datastore.name, str)
73
+ assert isinstance(project_datastore.project_uuid, str)
74
+ assert isinstance(project_datastore.type, str)
75
+ assert isinstance(project_datastore.region_uuid, str)
76
+
77
+ def test_project_datastore_str(self, project_datastore):
78
+ string = str(project_datastore)
79
+ regex = r"^{.*\"id\": \"" + project_datastore.id + r"\".*}$"
80
+ assert isinstance(string, str)
81
+ assert re.match(regex, string)
82
+
83
+ def test_project_datastore_repr(self, project_datastore):
84
+ string = repr(project_datastore)
85
+ regex = (
86
+ r"^ProjectDatastore\( trainml , \*\*{.*'id': '"
87
+ + project_datastore.id
88
+ + r"'.*}\)$"
89
+ )
90
+ assert isinstance(string, str)
91
+ assert re.match(regex, string)
92
+
93
+ def test_project_datastore_bool(self, project_datastore, mock_trainml):
94
+ empty_project_datastore = specimen.ProjectDatastore(mock_trainml)
95
+ assert bool(project_datastore)
96
+ assert not bool(empty_project_datastore)
@@ -0,0 +1,96 @@
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 trainml.projects.keys as specimen
9
+ from trainml.exceptions import (
10
+ ApiError,
11
+ SpecificationError,
12
+ TrainMLException,
13
+ )
14
+
15
+ pytestmark = [mark.sdk, mark.unit, mark.projects]
16
+
17
+
18
+ @fixture
19
+ def project_keys(mock_trainml):
20
+ yield specimen.ProjectKeys(mock_trainml, project_id="1")
21
+
22
+
23
+ @fixture
24
+ def project_key(mock_trainml):
25
+ yield specimen.ProjectKey(
26
+ mock_trainml, 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_trainml):
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_trainml._query = AsyncMock(return_value=api_response)
38
+ resp = await project_keys.list()
39
+ mock_trainml._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_trainml,
47
+ ):
48
+ api_response = dict()
49
+ mock_trainml._query = AsyncMock(return_value=api_response)
50
+ await project_keys.remove("aws")
51
+ mock_trainml._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_trainml):
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_trainml._query = AsyncMock(return_value=api_response)
66
+ response = await project_keys.put(**requested_config)
67
+ mock_trainml._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\( trainml , \*\*{.*'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_trainml):
94
+ empty_project_key = specimen.ProjectKey(mock_trainml)
95
+ assert bool(project_key)
96
+ assert not bool(empty_project_key)
@@ -0,0 +1,101 @@
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 trainml.projects.secrets as specimen
9
+ from trainml.exceptions import (
10
+ ApiError,
11
+ SpecificationError,
12
+ TrainMLException,
13
+ )
14
+
15
+ pytestmark = [mark.sdk, mark.unit, mark.projects]
16
+
17
+
18
+ @fixture
19
+ def project_secrets(mock_trainml):
20
+ yield specimen.ProjectSecrets(mock_trainml, project_id="1")
21
+
22
+
23
+ @fixture
24
+ def project_service(mock_trainml):
25
+ yield specimen.ProjectSecret(
26
+ mock_trainml,
27
+ project_uuid="proj-id-1",
28
+ name="secret_value",
29
+ )
30
+
31
+
32
+ class ProjectSecretsTests:
33
+ @mark.asyncio
34
+ async def test_project_secrets_list(self, project_secrets, mock_trainml):
35
+ api_response = [
36
+ {
37
+ "project_uuid": "proj-id-1",
38
+ "name": "secret_value",
39
+ },
40
+ {
41
+ "project_uuid": "proj-id-1",
42
+ "name": "secret_value_2",
43
+ },
44
+ ]
45
+ mock_trainml._query = AsyncMock(return_value=api_response)
46
+ resp = await project_secrets.list()
47
+ mock_trainml._query.assert_called_once_with("/project/1/secrets", "GET", dict())
48
+ assert len(resp) == 2
49
+
50
+ @mark.asyncio
51
+ async def test_remove_project_secret(
52
+ self,
53
+ project_secrets,
54
+ mock_trainml,
55
+ ):
56
+ api_response = dict()
57
+ mock_trainml._query = AsyncMock(return_value=api_response)
58
+ await project_secrets.remove("secret_value")
59
+ mock_trainml._query.assert_called_once_with(
60
+ "/project/1/secret/secret_value", "DELETE", dict()
61
+ )
62
+
63
+ @mark.asyncio
64
+ async def test_put_project_secret(self, project_secrets, mock_trainml):
65
+ requested_config = dict(name="secret_value", value="ASKHJSLKF")
66
+ expected_payload = dict(value="ASKHJSLKF")
67
+ api_response = {"project_uuid": "project-id-1", "name": "secret_value"}
68
+
69
+ mock_trainml._query = AsyncMock(return_value=api_response)
70
+ response = await project_secrets.put(**requested_config)
71
+ mock_trainml._query.assert_called_once_with(
72
+ "/project/1/secret/secret_value", "PUT", None, expected_payload
73
+ )
74
+ assert response.name == "secret_value"
75
+
76
+
77
+ class ProjectSecretTests:
78
+ def test_project_service_properties(self, project_service):
79
+ assert isinstance(project_service.name, str)
80
+ assert isinstance(project_service.project_uuid, str)
81
+
82
+ def test_project_service_str(self, project_service):
83
+ string = str(project_service)
84
+ regex = r"^{.*\"name\": \"" + project_service.name + r"\".*}$"
85
+ assert isinstance(string, str)
86
+ assert re.match(regex, string)
87
+
88
+ def test_project_service_repr(self, project_service):
89
+ string = repr(project_service)
90
+ regex = (
91
+ r"^ProjectSecret\( trainml , \*\*{.*'name': '"
92
+ + project_service.name
93
+ + r"'.*}\)$"
94
+ )
95
+ assert isinstance(string, str)
96
+ assert re.match(regex, string)
97
+
98
+ def test_project_service_bool(self, project_service, mock_trainml):
99
+ empty_project_service = specimen.ProjectSecret(mock_trainml)
100
+ assert bool(project_service)
101
+ assert not bool(empty_project_service)
@@ -0,0 +1,102 @@
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 trainml.projects.services as specimen
9
+ from trainml.exceptions import (
10
+ ApiError,
11
+ SpecificationError,
12
+ TrainMLException,
13
+ )
14
+
15
+ pytestmark = [mark.sdk, mark.unit, mark.projects]
16
+
17
+
18
+ @fixture
19
+ def project_services(mock_trainml):
20
+ yield specimen.ProjectServices(mock_trainml, project_id="1")
21
+
22
+
23
+ @fixture
24
+ def project_service(mock_trainml):
25
+ yield specimen.ProjectService(
26
+ mock_trainml,
27
+ id="res-id-1",
28
+ name="service 1",
29
+ project_uuid="proj-id-1",
30
+ region_uuid="reg-id-1",
31
+ public=False,
32
+ hostname="asdf.proximl.cloud",
33
+ )
34
+
35
+
36
+ class ProjectServicesTests:
37
+ @mark.asyncio
38
+ async def test_project_services_refresh(self, project_services, mock_trainml):
39
+ api_response = dict()
40
+ mock_trainml._query = AsyncMock(return_value=api_response)
41
+ await project_services.refresh()
42
+ mock_trainml._query.assert_called_once_with("/project/1/services", "PATCH")
43
+
44
+ @mark.asyncio
45
+ async def test_project_services_list(self, project_services, mock_trainml):
46
+ api_response = [
47
+ {
48
+ "project_uuid": "proj-id-1",
49
+ "region_uuid": "reg-id-1",
50
+ "id": "res-id-1",
51
+ "type": "port",
52
+ "name": "On-Prem Service A",
53
+ "resource": "8001",
54
+ "hostname": "service-a.local",
55
+ },
56
+ {
57
+ "project_uuid": "proj-id-1",
58
+ "region_uuid": "reg-id-2",
59
+ "id": "res-id-2",
60
+ "type": "port",
61
+ "name": "Cloud Service B",
62
+ "resource": "8001",
63
+ "hostname": "service-b.local",
64
+ },
65
+ ]
66
+ mock_trainml._query = AsyncMock(return_value=api_response)
67
+ resp = await project_services.list()
68
+ mock_trainml._query.assert_called_once_with(
69
+ "/project/1/services", "GET", dict()
70
+ )
71
+ assert len(resp) == 2
72
+
73
+
74
+ class ProjectServiceTests:
75
+ def test_project_service_properties(self, project_service):
76
+ assert isinstance(project_service.id, str)
77
+ assert isinstance(project_service.name, str)
78
+ assert isinstance(project_service.project_uuid, str)
79
+ assert isinstance(project_service.hostname, str)
80
+ assert isinstance(project_service.public, bool)
81
+ assert isinstance(project_service.region_uuid, str)
82
+
83
+ def test_project_service_str(self, project_service):
84
+ string = str(project_service)
85
+ regex = r"^{.*\"id\": \"" + project_service.id + r"\".*}$"
86
+ assert isinstance(string, str)
87
+ assert re.match(regex, string)
88
+
89
+ def test_project_service_repr(self, project_service):
90
+ string = repr(project_service)
91
+ regex = (
92
+ r"^ProjectService\( trainml , \*\*{.*'id': '"
93
+ + project_service.id
94
+ + r"'.*}\)$"
95
+ )
96
+ assert isinstance(string, str)
97
+ assert re.match(regex, string)
98
+
99
+ def test_project_service_bool(self, project_service, mock_trainml):
100
+ empty_project_service = specimen.ProjectService(mock_trainml)
101
+ assert bool(project_service)
102
+ assert not bool(empty_project_service)
@@ -0,0 +1,128 @@
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 trainml.projects as specimen
9
+ from trainml.exceptions import (
10
+ ApiError,
11
+ SpecificationError,
12
+ TrainMLException,
13
+ )
14
+
15
+ pytestmark = [mark.sdk, mark.unit, mark.projects]
16
+
17
+
18
+ @fixture
19
+ def projects(mock_trainml):
20
+ yield specimen.Projects(mock_trainml)
21
+
22
+
23
+ @fixture
24
+ def project(mock_trainml):
25
+ yield specimen.Project(
26
+ mock_trainml,
27
+ id="1",
28
+ name="My Mock Project",
29
+ owner=True,
30
+ owner_name="Me",
31
+ created_name="Me",
32
+ job_all=True,
33
+ dataset_all=True,
34
+ model_all=True,
35
+ createdAt="2020-12-31T23:59:59.000Z",
36
+ )
37
+
38
+
39
+ class ProjectsTests:
40
+ @mark.asyncio
41
+ async def test_get_project(
42
+ self,
43
+ projects,
44
+ mock_trainml,
45
+ ):
46
+ api_response = dict()
47
+ mock_trainml._query = AsyncMock(return_value=api_response)
48
+ await projects.get("1234")
49
+ mock_trainml._query.assert_called_once_with("/project/1234", "GET", dict())
50
+
51
+ @mark.asyncio
52
+ async def test_list_projects(
53
+ self,
54
+ projects,
55
+ mock_trainml,
56
+ ):
57
+ api_response = dict()
58
+ mock_trainml._query = AsyncMock(return_value=api_response)
59
+ await projects.list()
60
+ mock_trainml._query.assert_called_once_with("/project", "GET", dict())
61
+
62
+ @mark.asyncio
63
+ async def test_remove_project(
64
+ self,
65
+ projects,
66
+ mock_trainml,
67
+ ):
68
+ api_response = dict()
69
+ mock_trainml._query = AsyncMock(return_value=api_response)
70
+ await projects.remove("4567")
71
+ mock_trainml._query.assert_called_once_with("/project/4567", "DELETE", dict())
72
+
73
+ @mark.asyncio
74
+ async def test_create_project_simple(self, projects, mock_trainml):
75
+ requested_config = dict(
76
+ name="new project",
77
+ )
78
+ expected_payload = dict(name="new project", copy_keys=False, copy_secrets=False)
79
+ api_response = {
80
+ "id": "project-id-1",
81
+ "name": "new project",
82
+ "owner": True,
83
+ "owner_name": "Me",
84
+ "created_name": "Me",
85
+ "job_all": True,
86
+ "dataset_all": True,
87
+ "model_all": True,
88
+ "createdAt": "2020-12-31T23:59:59.000Z",
89
+ }
90
+
91
+ mock_trainml._query = AsyncMock(return_value=api_response)
92
+ response = await projects.create(**requested_config)
93
+ mock_trainml._query.assert_called_once_with(
94
+ "/project", "POST", None, expected_payload
95
+ )
96
+ assert response.id == "project-id-1"
97
+
98
+
99
+ class ProjectTests:
100
+ def test_project_properties(self, project):
101
+ assert isinstance(project.id, str)
102
+ assert isinstance(project.name, str)
103
+ assert isinstance(project.owner_name, str)
104
+ assert isinstance(project.is_owner, bool)
105
+
106
+ def test_project_str(self, project):
107
+ string = str(project)
108
+ regex = r"^{.*\"id\": \"" + project.id + r"\".*}$"
109
+ assert isinstance(string, str)
110
+ assert re.match(regex, string)
111
+
112
+ def test_project_repr(self, project):
113
+ string = repr(project)
114
+ regex = r"^Project\( trainml , \*\*{.*'id': '" + project.id + r"'.*}\)$"
115
+ assert isinstance(string, str)
116
+ assert re.match(regex, string)
117
+
118
+ def test_project_bool(self, project, mock_trainml):
119
+ empty_project = specimen.Project(mock_trainml)
120
+ assert bool(project)
121
+ assert not bool(empty_project)
122
+
123
+ @mark.asyncio
124
+ async def test_project_remove(self, project, mock_trainml):
125
+ api_response = dict()
126
+ mock_trainml._query = AsyncMock(return_value=api_response)
127
+ await project.remove()
128
+ mock_trainml._query.assert_called_once_with("/project/1", "DELETE")