datacrunch 1.15.0__py3-none-any.whl → 1.16.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.
- datacrunch/InferenceClient/inference_client.py +200 -65
- datacrunch/__init__.py +2 -0
- datacrunch/_version.py +6 -0
- datacrunch/authentication/authentication.py +7 -14
- datacrunch/balance/balance.py +1 -3
- datacrunch/constants.py +19 -17
- datacrunch/containers/containers.py +151 -123
- datacrunch/datacrunch.py +18 -18
- datacrunch/helpers.py +7 -2
- datacrunch/http_client/http_client.py +14 -14
- datacrunch/images/images.py +9 -3
- datacrunch/instance_types/instance_types.py +42 -35
- datacrunch/instances/instances.py +62 -50
- datacrunch/locations/locations.py +1 -2
- datacrunch/ssh_keys/ssh_keys.py +3 -4
- datacrunch/startup_scripts/startup_scripts.py +10 -8
- datacrunch/volume_types/volume_types.py +10 -8
- datacrunch/volumes/volumes.py +60 -73
- {datacrunch-1.15.0.dist-info → datacrunch-1.16.0.dist-info}/METADATA +46 -72
- datacrunch-1.16.0.dist-info/RECORD +35 -0
- datacrunch-1.16.0.dist-info/WHEEL +4 -0
- datacrunch/__version__.py +0 -1
- datacrunch-1.15.0.dist-info/RECORD +0 -69
- datacrunch-1.15.0.dist-info/WHEEL +0 -5
- datacrunch-1.15.0.dist-info/licenses/LICENSE +0 -21
- datacrunch-1.15.0.dist-info/top_level.txt +0 -2
- tests/__init__.py +0 -0
- tests/integration_tests/__init__.py +0 -0
- tests/integration_tests/conftest.py +0 -20
- tests/integration_tests/test_instances.py +0 -36
- tests/integration_tests/test_locations.py +0 -65
- tests/integration_tests/test_volumes.py +0 -94
- tests/unit_tests/__init__.py +0 -0
- tests/unit_tests/authentication/__init__.py +0 -0
- tests/unit_tests/authentication/test_authentication.py +0 -202
- tests/unit_tests/balance/__init__.py +0 -0
- tests/unit_tests/balance/test_balance.py +0 -25
- tests/unit_tests/conftest.py +0 -21
- tests/unit_tests/containers/__init__.py +0 -1
- tests/unit_tests/containers/test_containers.py +0 -959
- tests/unit_tests/http_client/__init__.py +0 -0
- tests/unit_tests/http_client/test_http_client.py +0 -193
- tests/unit_tests/images/__init__.py +0 -0
- tests/unit_tests/images/test_images.py +0 -41
- tests/unit_tests/instance_types/__init__.py +0 -0
- tests/unit_tests/instance_types/test_instance_types.py +0 -87
- tests/unit_tests/instances/__init__.py +0 -0
- tests/unit_tests/instances/test_instances.py +0 -483
- tests/unit_tests/ssh_keys/__init__.py +0 -0
- tests/unit_tests/ssh_keys/test_ssh_keys.py +0 -198
- tests/unit_tests/startup_scripts/__init__.py +0 -0
- tests/unit_tests/startup_scripts/test_startup_scripts.py +0 -196
- tests/unit_tests/test_datacrunch.py +0 -65
- tests/unit_tests/test_exceptions.py +0 -33
- tests/unit_tests/volume_types/__init__.py +0 -0
- tests/unit_tests/volume_types/test_volume_types.py +0 -50
- tests/unit_tests/volumes/__init__.py +0 -0
- tests/unit_tests/volumes/test_volumes.py +0 -641
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
import responses # https://github.com/getsentry/responses
|
|
3
|
-
|
|
4
|
-
from datacrunch.exceptions import APIException
|
|
5
|
-
from datacrunch.startup_scripts.startup_scripts import StartupScriptsService, StartupScript
|
|
6
|
-
|
|
7
|
-
INVALID_REQUEST = 'invalid_request'
|
|
8
|
-
INVALID_REQUEST_MESSAGE = 'Your existence is invalid'
|
|
9
|
-
|
|
10
|
-
SCRIPT_ID = 'deadc0de-a5d2-4972-ae4e-d429115d055b'
|
|
11
|
-
SCRIPT_NAME = 'next episode of _____'
|
|
12
|
-
SCRIPT_VALUE = 'this was not in the script!'
|
|
13
|
-
|
|
14
|
-
script_ID_2 = 'beefbeef-a5d2-4972-ae4e-d429115d055b'
|
|
15
|
-
|
|
16
|
-
PAYLOAD = [
|
|
17
|
-
{
|
|
18
|
-
'id': SCRIPT_ID,
|
|
19
|
-
'name': SCRIPT_NAME,
|
|
20
|
-
'script': SCRIPT_VALUE
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class TestStartupScripts:
|
|
26
|
-
|
|
27
|
-
@pytest.fixture
|
|
28
|
-
def startup_script_service(self, http_client):
|
|
29
|
-
return StartupScriptsService(http_client)
|
|
30
|
-
|
|
31
|
-
@pytest.fixture
|
|
32
|
-
def endpoint(self, http_client):
|
|
33
|
-
return http_client._base_url + "/scripts"
|
|
34
|
-
|
|
35
|
-
def test_get_scripts(self, startup_script_service, endpoint):
|
|
36
|
-
# arrange - add response mock
|
|
37
|
-
responses.add(
|
|
38
|
-
responses.GET,
|
|
39
|
-
endpoint,
|
|
40
|
-
json=PAYLOAD,
|
|
41
|
-
status=200
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
# act
|
|
45
|
-
scripts = startup_script_service.get()
|
|
46
|
-
|
|
47
|
-
# assert
|
|
48
|
-
assert type(scripts) == list
|
|
49
|
-
assert len(scripts) == 1
|
|
50
|
-
assert type(scripts[0]) == StartupScript
|
|
51
|
-
assert scripts[0].id == SCRIPT_ID
|
|
52
|
-
assert scripts[0].name == SCRIPT_NAME
|
|
53
|
-
assert scripts[0].script == SCRIPT_VALUE
|
|
54
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
55
|
-
|
|
56
|
-
def test_get_script_by_id_successful(self, startup_script_service, endpoint):
|
|
57
|
-
# arrange - add response mock
|
|
58
|
-
url = endpoint + '/' + SCRIPT_ID
|
|
59
|
-
responses.add(
|
|
60
|
-
responses.GET,
|
|
61
|
-
url,
|
|
62
|
-
json=PAYLOAD,
|
|
63
|
-
status=200
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
# act
|
|
67
|
-
script = startup_script_service.get_by_id(SCRIPT_ID)
|
|
68
|
-
|
|
69
|
-
# assert
|
|
70
|
-
assert type(script) == StartupScript
|
|
71
|
-
assert script.id == SCRIPT_ID
|
|
72
|
-
assert script.name == SCRIPT_NAME
|
|
73
|
-
assert script.script == SCRIPT_VALUE
|
|
74
|
-
assert responses.assert_call_count(url, 1) is True
|
|
75
|
-
|
|
76
|
-
def test_get_script_by_id_failed(self, startup_script_service, endpoint):
|
|
77
|
-
# arrange - add response mock
|
|
78
|
-
url = endpoint + '/x'
|
|
79
|
-
responses.add(
|
|
80
|
-
responses.GET,
|
|
81
|
-
url,
|
|
82
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
83
|
-
status=400
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
# act
|
|
87
|
-
with pytest.raises(APIException) as excinfo:
|
|
88
|
-
startup_script_service.get_by_id('x')
|
|
89
|
-
|
|
90
|
-
# assert
|
|
91
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
92
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
93
|
-
assert responses.assert_call_count(url, 1) is True
|
|
94
|
-
|
|
95
|
-
def test_create_script_successful(self, startup_script_service, endpoint):
|
|
96
|
-
# arrange - add response mock
|
|
97
|
-
responses.add(
|
|
98
|
-
responses.POST,
|
|
99
|
-
endpoint,
|
|
100
|
-
body=SCRIPT_ID,
|
|
101
|
-
status=201
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
# act
|
|
105
|
-
script = startup_script_service.create(SCRIPT_NAME, SCRIPT_VALUE)
|
|
106
|
-
|
|
107
|
-
# assert
|
|
108
|
-
assert type(script) == StartupScript
|
|
109
|
-
assert script.id == SCRIPT_ID
|
|
110
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
111
|
-
|
|
112
|
-
def test_create_script_failed(self, startup_script_service, endpoint):
|
|
113
|
-
# arrange - add response mock
|
|
114
|
-
responses.add(
|
|
115
|
-
responses.POST,
|
|
116
|
-
endpoint,
|
|
117
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
118
|
-
status=400
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
# act
|
|
122
|
-
with pytest.raises(APIException) as excinfo:
|
|
123
|
-
startup_script_service.create(SCRIPT_NAME, SCRIPT_VALUE)
|
|
124
|
-
|
|
125
|
-
# assert
|
|
126
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
127
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
128
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
129
|
-
|
|
130
|
-
def test_delete_scripts_successful(self, startup_script_service, endpoint):
|
|
131
|
-
# arrange - add response mock
|
|
132
|
-
responses.add(
|
|
133
|
-
responses.DELETE,
|
|
134
|
-
endpoint,
|
|
135
|
-
status=200
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
# act
|
|
139
|
-
result = startup_script_service.delete([SCRIPT_ID, script_ID_2])
|
|
140
|
-
|
|
141
|
-
# assert
|
|
142
|
-
assert result is None
|
|
143
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
144
|
-
|
|
145
|
-
def test_delete_scripts_failed(self, startup_script_service, endpoint):
|
|
146
|
-
# arrange - add response mock
|
|
147
|
-
responses.add(
|
|
148
|
-
responses.DELETE,
|
|
149
|
-
endpoint,
|
|
150
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
151
|
-
status=400
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
# act
|
|
155
|
-
with pytest.raises(APIException) as excinfo:
|
|
156
|
-
startup_script_service.delete(['x'])
|
|
157
|
-
|
|
158
|
-
# assert
|
|
159
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
160
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
161
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
162
|
-
|
|
163
|
-
def test_delete_script_by_id_successful(self, startup_script_service, endpoint):
|
|
164
|
-
# arrange - add response mock
|
|
165
|
-
url = endpoint + '/' + SCRIPT_ID
|
|
166
|
-
responses.add(
|
|
167
|
-
responses.DELETE,
|
|
168
|
-
url,
|
|
169
|
-
status=200
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
# act
|
|
173
|
-
result = startup_script_service.delete_by_id(SCRIPT_ID)
|
|
174
|
-
|
|
175
|
-
# assert
|
|
176
|
-
assert result is None
|
|
177
|
-
assert responses.assert_call_count(url, 1) is True
|
|
178
|
-
|
|
179
|
-
def test_delete_script_by_id_failed(self, startup_script_service, endpoint):
|
|
180
|
-
# arrange - add response mock
|
|
181
|
-
url = endpoint + '/x'
|
|
182
|
-
responses.add(
|
|
183
|
-
responses.DELETE,
|
|
184
|
-
url,
|
|
185
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
186
|
-
status=400
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
# act
|
|
190
|
-
with pytest.raises(APIException) as excinfo:
|
|
191
|
-
startup_script_service.delete_by_id('x')
|
|
192
|
-
|
|
193
|
-
# assert
|
|
194
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
195
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
196
|
-
assert responses.assert_call_count(url, 1) is True
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
import responses # https://github.com/getsentry/responses
|
|
3
|
-
from datacrunch.datacrunch import DataCrunchClient
|
|
4
|
-
from datacrunch.exceptions import APIException
|
|
5
|
-
|
|
6
|
-
BASE_URL = "https://api-testing.datacrunch.io/v1"
|
|
7
|
-
|
|
8
|
-
response_json = {
|
|
9
|
-
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJoZXkiOiJ5b3UgYWN1YWxseSBjaGVja2VkIHRoaXM_In0.0RjcdKQ1NJP9gbRyXITE6LFFLwKGzeeshuubnkkfkb8",
|
|
10
|
-
"token_type": "Bearer",
|
|
11
|
-
"expires_in": 3600,
|
|
12
|
-
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3b3ciOiJhbmQgdGhpcyB0b28_In0.AC5gk-o-MOptUgrouEErlhr8WT3Hg_RR6px6A0I7ZEk",
|
|
13
|
-
"scope": "fullAccess"
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
class TestDataCrunchClient:
|
|
17
|
-
|
|
18
|
-
def test_client(self):
|
|
19
|
-
# arrange - add response mock
|
|
20
|
-
responses.add(
|
|
21
|
-
responses.POST,
|
|
22
|
-
BASE_URL + "/oauth2/token",
|
|
23
|
-
json=response_json,
|
|
24
|
-
status=200
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
# act
|
|
28
|
-
client = DataCrunchClient("XXXXXXXXXXXXXX", "XXXXXXXXXXXXXX", BASE_URL)
|
|
29
|
-
|
|
30
|
-
# assert
|
|
31
|
-
assert client.constants.base_url == BASE_URL
|
|
32
|
-
|
|
33
|
-
def test_client_with_default_base_url(self):
|
|
34
|
-
# arrange - add response mock
|
|
35
|
-
DEFAULT_BASE_URL = "https://api.datacrunch.io/v1"
|
|
36
|
-
responses.add(
|
|
37
|
-
responses.POST,
|
|
38
|
-
DEFAULT_BASE_URL + "/oauth2/token",
|
|
39
|
-
json=response_json,
|
|
40
|
-
status=200
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
# act
|
|
44
|
-
client = DataCrunchClient("XXXXXXXXXXXXXX", "XXXXXXXXXXXXXX")
|
|
45
|
-
|
|
46
|
-
# assert
|
|
47
|
-
assert client.constants.base_url == DEFAULT_BASE_URL
|
|
48
|
-
|
|
49
|
-
def test_invalid_client_credentials(self):
|
|
50
|
-
# arrange - add response mock
|
|
51
|
-
responses.add(
|
|
52
|
-
responses.POST,
|
|
53
|
-
BASE_URL + "/oauth2/token",
|
|
54
|
-
json={"code": "unauthorized_request", "message": "Invalid client id or client secret"},
|
|
55
|
-
status=401
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
# act
|
|
59
|
-
with pytest.raises(APIException) as excinfo:
|
|
60
|
-
DataCrunchClient("x", "y", BASE_URL)
|
|
61
|
-
|
|
62
|
-
# assert
|
|
63
|
-
assert excinfo.value.code == 'unauthorized_request'
|
|
64
|
-
assert excinfo.value.message == 'Invalid client id or client secret'
|
|
65
|
-
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
from datacrunch.exceptions import APIException
|
|
3
|
-
|
|
4
|
-
ERROR_CODE = 'test_code'
|
|
5
|
-
ERROR_MESSAGE = "test message"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def test_api_exception_with_code():
|
|
9
|
-
# arrange
|
|
10
|
-
error_str = f'error code: {ERROR_CODE}\nmessage: {ERROR_MESSAGE}'
|
|
11
|
-
|
|
12
|
-
# act
|
|
13
|
-
with pytest.raises(APIException) as excinfo:
|
|
14
|
-
raise APIException(ERROR_CODE, ERROR_MESSAGE)
|
|
15
|
-
|
|
16
|
-
# assert
|
|
17
|
-
assert excinfo.value.code == ERROR_CODE
|
|
18
|
-
assert excinfo.value.message == ERROR_MESSAGE
|
|
19
|
-
assert excinfo.value.__str__() == error_str
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def test_api_exception_without_code():
|
|
23
|
-
# arrange
|
|
24
|
-
error_str = f'message: {ERROR_MESSAGE}'
|
|
25
|
-
|
|
26
|
-
# act
|
|
27
|
-
with pytest.raises(APIException) as excinfo:
|
|
28
|
-
raise APIException(None, ERROR_MESSAGE)
|
|
29
|
-
|
|
30
|
-
# assert
|
|
31
|
-
assert excinfo.value.code is None
|
|
32
|
-
assert excinfo.value.message == ERROR_MESSAGE
|
|
33
|
-
assert excinfo.value.__str__() == error_str
|
|
File without changes
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import responses # https://github.com/getsentry/responses
|
|
2
|
-
|
|
3
|
-
from datacrunch.volume_types.volume_types import VolumeTypesService, VolumeType
|
|
4
|
-
from datacrunch.constants import VolumeTypes
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
USD = "usd"
|
|
8
|
-
NVMe_PRICE = 0.2
|
|
9
|
-
HDD_PRICE = 0.05
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def test_volume_types(http_client):
|
|
13
|
-
responses.add(
|
|
14
|
-
responses.GET,
|
|
15
|
-
http_client._base_url + "/volume-types",
|
|
16
|
-
json=[
|
|
17
|
-
{
|
|
18
|
-
"type": VolumeTypes.NVMe,
|
|
19
|
-
"price": {
|
|
20
|
-
"currency": USD,
|
|
21
|
-
"price_per_month_per_gb": NVMe_PRICE
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"type": VolumeTypes.HDD,
|
|
26
|
-
"price": {
|
|
27
|
-
"currency": USD,
|
|
28
|
-
"price_per_month_per_gb": HDD_PRICE
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
],
|
|
32
|
-
status=200
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
volume_types_service = VolumeTypesService(http_client)
|
|
36
|
-
|
|
37
|
-
# act
|
|
38
|
-
volumes_types = volume_types_service.get()
|
|
39
|
-
nvme_type = volumes_types[0]
|
|
40
|
-
hdd_type = volumes_types[1]
|
|
41
|
-
|
|
42
|
-
# assert
|
|
43
|
-
assert type(volumes_types) == list
|
|
44
|
-
assert len(volumes_types) == 2
|
|
45
|
-
assert type(nvme_type) == VolumeType
|
|
46
|
-
assert type(hdd_type) == VolumeType
|
|
47
|
-
assert nvme_type.type == VolumeTypes.NVMe
|
|
48
|
-
assert nvme_type.price_per_month_per_gb == NVMe_PRICE
|
|
49
|
-
assert hdd_type.type == VolumeTypes.HDD
|
|
50
|
-
assert hdd_type.price_per_month_per_gb == HDD_PRICE
|
|
File without changes
|