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
|
@@ -2,7 +2,7 @@ import requests
|
|
|
2
2
|
import json
|
|
3
3
|
|
|
4
4
|
from datacrunch.exceptions import APIException
|
|
5
|
-
from datacrunch.
|
|
5
|
+
from datacrunch._version import __version__
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def handle_error(response: requests.Response) -> None:
|
|
@@ -27,7 +27,7 @@ class HTTPClient:
|
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
29
|
def __init__(self, auth_service, base_url: str) -> None:
|
|
30
|
-
self._version =
|
|
30
|
+
self._version = __version__
|
|
31
31
|
self._base_url = base_url
|
|
32
32
|
self._auth_service = auth_service
|
|
33
33
|
self._auth_service.authenticate()
|
|
@@ -56,8 +56,7 @@ class HTTPClient:
|
|
|
56
56
|
url = self._add_base_url(url)
|
|
57
57
|
headers = self._generate_headers()
|
|
58
58
|
|
|
59
|
-
response = requests.post(
|
|
60
|
-
url, json=json, headers=headers, params=params, **kwargs)
|
|
59
|
+
response = requests.post(url, json=json, headers=headers, params=params, **kwargs)
|
|
61
60
|
handle_error(response)
|
|
62
61
|
|
|
63
62
|
return response
|
|
@@ -86,8 +85,7 @@ class HTTPClient:
|
|
|
86
85
|
url = self._add_base_url(url)
|
|
87
86
|
headers = self._generate_headers()
|
|
88
87
|
|
|
89
|
-
response = requests.put(
|
|
90
|
-
url, json=json, headers=headers, params=params, **kwargs)
|
|
88
|
+
response = requests.put(url, json=json, headers=headers, params=params, **kwargs)
|
|
91
89
|
handle_error(response)
|
|
92
90
|
|
|
93
91
|
return response
|
|
@@ -119,7 +117,9 @@ class HTTPClient:
|
|
|
119
117
|
|
|
120
118
|
return response
|
|
121
119
|
|
|
122
|
-
def patch(
|
|
120
|
+
def patch(
|
|
121
|
+
self, url: str, json: dict = None, params: dict = None, **kwargs
|
|
122
|
+
) -> requests.Response:
|
|
123
123
|
"""Sends a PATCH request.
|
|
124
124
|
|
|
125
125
|
A wrapper for the requests.patch method.
|
|
@@ -143,13 +143,14 @@ class HTTPClient:
|
|
|
143
143
|
url = self._add_base_url(url)
|
|
144
144
|
headers = self._generate_headers()
|
|
145
145
|
|
|
146
|
-
response = requests.patch(
|
|
147
|
-
url, json=json, headers=headers, params=params, **kwargs)
|
|
146
|
+
response = requests.patch(url, json=json, headers=headers, params=params, **kwargs)
|
|
148
147
|
handle_error(response)
|
|
149
148
|
|
|
150
149
|
return response
|
|
151
150
|
|
|
152
|
-
def delete(
|
|
151
|
+
def delete(
|
|
152
|
+
self, url: str, json: dict = None, params: dict = None, **kwargs
|
|
153
|
+
) -> requests.Response:
|
|
153
154
|
"""Sends a DELETE request.
|
|
154
155
|
|
|
155
156
|
A wrapper for the requests.delete method.
|
|
@@ -173,8 +174,7 @@ class HTTPClient:
|
|
|
173
174
|
url = self._add_base_url(url)
|
|
174
175
|
headers = self._generate_headers()
|
|
175
176
|
|
|
176
|
-
response = requests.delete(
|
|
177
|
-
url, headers=headers, json=json, params=params, **kwargs)
|
|
177
|
+
response = requests.delete(url, headers=headers, json=json, params=params, **kwargs)
|
|
178
178
|
handle_error(response)
|
|
179
179
|
|
|
180
180
|
return response
|
|
@@ -186,7 +186,7 @@ class HTTPClient:
|
|
|
186
186
|
|
|
187
187
|
:raises APIException: an api exception with message and error type code
|
|
188
188
|
"""
|
|
189
|
-
if
|
|
189
|
+
if self._auth_service.is_expired():
|
|
190
190
|
# try to refresh. if refresh token has expired, reauthenticate
|
|
191
191
|
try:
|
|
192
192
|
self._auth_service.refresh()
|
|
@@ -202,7 +202,7 @@ class HTTPClient:
|
|
|
202
202
|
headers = {
|
|
203
203
|
'Authorization': self._generate_bearer_header(),
|
|
204
204
|
'User-Agent': self._generate_user_agent(),
|
|
205
|
-
'Content-Type': 'application/json'
|
|
205
|
+
'Content-Type': 'application/json',
|
|
206
206
|
}
|
|
207
207
|
return headers
|
|
208
208
|
|
datacrunch/images/images.py
CHANGED
|
@@ -76,12 +76,18 @@ class ImagesService:
|
|
|
76
76
|
self._http_client = http_client
|
|
77
77
|
|
|
78
78
|
def get(self) -> List[Image]:
|
|
79
|
-
"""Get the available instance images
|
|
79
|
+
"""Get the available instance images
|
|
80
80
|
|
|
81
81
|
:return: list of images objects
|
|
82
82
|
:rtype: List[Image]
|
|
83
83
|
"""
|
|
84
84
|
images = self._http_client.get(IMAGES_ENDPOINT).json()
|
|
85
|
-
image_objects = list(
|
|
86
|
-
|
|
85
|
+
image_objects = list(
|
|
86
|
+
map(
|
|
87
|
+
lambda image: Image(
|
|
88
|
+
image['id'], image['name'], image['image_type'], image['details']
|
|
89
|
+
),
|
|
90
|
+
images,
|
|
91
|
+
)
|
|
92
|
+
)
|
|
87
93
|
return image_objects
|
|
@@ -4,18 +4,19 @@ INSTANCE_TYPES_ENDPOINT = '/instance-types'
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class InstanceType:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
id: str,
|
|
10
|
+
instance_type: str,
|
|
11
|
+
price_per_hour: float,
|
|
12
|
+
spot_price_per_hour: float,
|
|
13
|
+
description: str,
|
|
14
|
+
cpu: dict,
|
|
15
|
+
gpu: dict,
|
|
16
|
+
memory: dict,
|
|
17
|
+
gpu_memory: dict,
|
|
18
|
+
storage: dict,
|
|
19
|
+
) -> None:
|
|
19
20
|
"""Initialize an instance type object
|
|
20
21
|
|
|
21
22
|
:param id: instance type id
|
|
@@ -146,17 +147,18 @@ class InstanceType:
|
|
|
146
147
|
:return: instance type string representation
|
|
147
148
|
:rtype: str
|
|
148
149
|
"""
|
|
149
|
-
return (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
150
|
+
return (
|
|
151
|
+
f'id: {self._id}\n'
|
|
152
|
+
f'instance type: {self._instance_type}\n'
|
|
153
|
+
f'price_per_hour: ${self._price_per_hour}\n'
|
|
154
|
+
f'spot_price_per_hour: ${self._spot_price_per_hour}\n'
|
|
155
|
+
f'description: {self._description}\n'
|
|
156
|
+
f'cpu: {self._cpu}\n'
|
|
157
|
+
f'gpu: {self._gpu}\n'
|
|
158
|
+
f'memory :{self._memory}\n'
|
|
159
|
+
f'gpu_memory :{self._gpu_memory}\n'
|
|
160
|
+
f'storage :{self._storage}\n'
|
|
161
|
+
)
|
|
160
162
|
|
|
161
163
|
|
|
162
164
|
class InstanceTypesService:
|
|
@@ -172,17 +174,22 @@ class InstanceTypesService:
|
|
|
172
174
|
:rtype: List[InstanceType]
|
|
173
175
|
"""
|
|
174
176
|
instance_types = self._http_client.get(INSTANCE_TYPES_ENDPOINT).json()
|
|
175
|
-
instance_type_objects = list(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
177
|
+
instance_type_objects = list(
|
|
178
|
+
map(
|
|
179
|
+
lambda instance_type: InstanceType(
|
|
180
|
+
id=instance_type['id'],
|
|
181
|
+
instance_type=instance_type['instance_type'],
|
|
182
|
+
price_per_hour=instance_type['price_per_hour'],
|
|
183
|
+
spot_price_per_hour=instance_type['spot_price'],
|
|
184
|
+
description=instance_type['description'],
|
|
185
|
+
cpu=instance_type['cpu'],
|
|
186
|
+
gpu=instance_type['gpu'],
|
|
187
|
+
memory=instance_type['memory'],
|
|
188
|
+
gpu_memory=instance_type['gpu_memory'],
|
|
189
|
+
storage=instance_type['storage'],
|
|
190
|
+
),
|
|
191
|
+
instance_types,
|
|
192
|
+
)
|
|
193
|
+
)
|
|
187
194
|
|
|
188
195
|
return instance_type_objects
|
|
@@ -32,7 +32,7 @@ class Instance:
|
|
|
32
32
|
gpu_memory: GPU memory configuration details.
|
|
33
33
|
ip: IP address assigned to the instance.
|
|
34
34
|
os_volume_id: ID of the operating system volume.
|
|
35
|
-
location: Datacenter location code (default: Locations.
|
|
35
|
+
location: Datacenter location code (default: Locations.FIN_03).
|
|
36
36
|
image: Image ID or type used for the instance.
|
|
37
37
|
startup_script_id: ID of the startup script to run.
|
|
38
38
|
is_spot: Whether the instance is a spot instance.
|
|
@@ -57,7 +57,7 @@ class Instance:
|
|
|
57
57
|
ip: Optional[str] = None
|
|
58
58
|
# Can be None if instance is still not provisioned
|
|
59
59
|
os_volume_id: Optional[str] = None
|
|
60
|
-
location: str = Locations.
|
|
60
|
+
location: str = Locations.FIN_03
|
|
61
61
|
image: Optional[str] = None
|
|
62
62
|
startup_script_id: Optional[str] = None
|
|
63
63
|
is_spot: bool = False
|
|
@@ -90,9 +90,11 @@ class InstancesService:
|
|
|
90
90
|
Returns:
|
|
91
91
|
List of instance objects matching the criteria.
|
|
92
92
|
"""
|
|
93
|
-
instances_dict = self._http_client.get(
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
instances_dict = self._http_client.get(INSTANCES_ENDPOINT, params={'status': status}).json()
|
|
94
|
+
return [
|
|
95
|
+
Instance.from_dict(instance_dict, infer_missing=True)
|
|
96
|
+
for instance_dict in instances_dict
|
|
97
|
+
]
|
|
96
98
|
|
|
97
99
|
def get_by_id(self, id: str) -> Instance:
|
|
98
100
|
"""Retrieves a specific instance by its ID.
|
|
@@ -106,30 +108,31 @@ class InstancesService:
|
|
|
106
108
|
Raises:
|
|
107
109
|
HTTPError: If the instance is not found or other API error occurs.
|
|
108
110
|
"""
|
|
109
|
-
instance_dict = self._http_client.get(
|
|
110
|
-
INSTANCES_ENDPOINT + f'/{id}').json()
|
|
111
|
+
instance_dict = self._http_client.get(INSTANCES_ENDPOINT + f'/{id}').json()
|
|
111
112
|
return Instance.from_dict(instance_dict, infer_missing=True)
|
|
112
113
|
|
|
113
|
-
def create(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
114
|
+
def create(
|
|
115
|
+
self,
|
|
116
|
+
instance_type: str,
|
|
117
|
+
image: str,
|
|
118
|
+
hostname: str,
|
|
119
|
+
description: str,
|
|
120
|
+
ssh_key_ids: list = [],
|
|
121
|
+
location: str = Locations.FIN_03,
|
|
122
|
+
startup_script_id: Optional[str] = None,
|
|
123
|
+
volumes: Optional[List[Dict]] = None,
|
|
124
|
+
existing_volumes: Optional[List[str]] = None,
|
|
125
|
+
os_volume: Optional[Dict] = None,
|
|
126
|
+
is_spot: bool = False,
|
|
127
|
+
contract: Optional[Contract] = None,
|
|
128
|
+
pricing: Optional[Pricing] = None,
|
|
129
|
+
coupon: Optional[str] = None,
|
|
130
|
+
*,
|
|
131
|
+
max_wait_time: float = 180,
|
|
132
|
+
initial_interval: float = 0.5,
|
|
133
|
+
max_interval: float = 5,
|
|
134
|
+
backoff_coefficient: float = 2.0,
|
|
135
|
+
) -> Instance:
|
|
133
136
|
"""Creates and deploys a new cloud instance.
|
|
134
137
|
|
|
135
138
|
Args:
|
|
@@ -138,7 +141,7 @@ class InstancesService:
|
|
|
138
141
|
hostname: Network hostname for the instance.
|
|
139
142
|
description: Human-readable description of the instance.
|
|
140
143
|
ssh_key_ids: List of SSH key IDs to associate with the instance.
|
|
141
|
-
location: Datacenter location code (default: Locations.
|
|
144
|
+
location: Datacenter location code (default: Locations.FIN_03).
|
|
142
145
|
startup_script_id: Optional ID of startup script to run.
|
|
143
146
|
volumes: Optional list of volume configurations to create.
|
|
144
147
|
existing_volumes: Optional list of existing volume IDs to attach.
|
|
@@ -159,18 +162,18 @@ class InstancesService:
|
|
|
159
162
|
HTTPError: If instance creation fails or other API error occurs.
|
|
160
163
|
"""
|
|
161
164
|
payload = {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
165
|
+
'instance_type': instance_type,
|
|
166
|
+
'image': image,
|
|
167
|
+
'ssh_key_ids': ssh_key_ids,
|
|
168
|
+
'startup_script_id': startup_script_id,
|
|
169
|
+
'hostname': hostname,
|
|
170
|
+
'description': description,
|
|
171
|
+
'location_code': location,
|
|
172
|
+
'os_volume': os_volume,
|
|
173
|
+
'volumes': volumes,
|
|
174
|
+
'existing_volumes': existing_volumes,
|
|
175
|
+
'is_spot': is_spot,
|
|
176
|
+
'coupon': coupon,
|
|
174
177
|
}
|
|
175
178
|
if contract:
|
|
176
179
|
payload['contract'] = contract
|
|
@@ -188,12 +191,18 @@ class InstancesService:
|
|
|
188
191
|
now = time.monotonic()
|
|
189
192
|
if now >= deadline:
|
|
190
193
|
raise TimeoutError(
|
|
191
|
-
f
|
|
194
|
+
f'Instance {id} did not enter provisioning state within {max_wait_time:.1f} seconds'
|
|
195
|
+
)
|
|
192
196
|
|
|
193
|
-
interval = min(initial_interval * backoff_coefficient
|
|
197
|
+
interval = min(initial_interval * backoff_coefficient**i, max_interval, deadline - now)
|
|
194
198
|
time.sleep(interval)
|
|
195
199
|
|
|
196
|
-
def action(
|
|
200
|
+
def action(
|
|
201
|
+
self,
|
|
202
|
+
id_list: Union[List[str], str],
|
|
203
|
+
action: str,
|
|
204
|
+
volume_ids: Optional[List[str]] = None,
|
|
205
|
+
) -> None:
|
|
197
206
|
"""Performs an action on one or more instances.
|
|
198
207
|
|
|
199
208
|
Args:
|
|
@@ -207,16 +216,17 @@ class InstancesService:
|
|
|
207
216
|
if type(id_list) is str:
|
|
208
217
|
id_list = [id_list]
|
|
209
218
|
|
|
210
|
-
payload = {
|
|
211
|
-
"id": id_list,
|
|
212
|
-
"action": action,
|
|
213
|
-
"volume_ids": volume_ids
|
|
214
|
-
}
|
|
219
|
+
payload = {'id': id_list, 'action': action, 'volume_ids': volume_ids}
|
|
215
220
|
|
|
216
221
|
self._http_client.put(INSTANCES_ENDPOINT, json=payload)
|
|
217
222
|
return
|
|
218
223
|
|
|
219
|
-
def is_available(
|
|
224
|
+
def is_available(
|
|
225
|
+
self,
|
|
226
|
+
instance_type: str,
|
|
227
|
+
is_spot: bool = False,
|
|
228
|
+
location_code: Optional[str] = None,
|
|
229
|
+
) -> bool:
|
|
220
230
|
"""Checks if a specific instance type is available for deployment.
|
|
221
231
|
|
|
222
232
|
Args:
|
|
@@ -232,7 +242,9 @@ class InstancesService:
|
|
|
232
242
|
url = f'/instance-availability/{instance_type}'
|
|
233
243
|
return self._http_client.get(url, query_params).json()
|
|
234
244
|
|
|
235
|
-
def get_availabilities(
|
|
245
|
+
def get_availabilities(
|
|
246
|
+
self, is_spot: Optional[bool] = None, location_code: Optional[str] = None
|
|
247
|
+
) -> List[Dict]:
|
|
236
248
|
"""Retrieves a list of available instance types across locations.
|
|
237
249
|
|
|
238
250
|
Args:
|
datacrunch/ssh_keys/ssh_keys.py
CHANGED
|
@@ -61,8 +61,7 @@ class SSHKeysService:
|
|
|
61
61
|
:rtype: List[SSHKey]
|
|
62
62
|
"""
|
|
63
63
|
keys = self._http_client.get(SSHKEYS_ENDPOINT).json()
|
|
64
|
-
keys_object_list = list(map(lambda key: SSHKey(
|
|
65
|
-
key['id'], key['name'], key['key']), keys))
|
|
64
|
+
keys_object_list = list(map(lambda key: SSHKey(key['id'], key['name'], key['key']), keys))
|
|
66
65
|
|
|
67
66
|
return keys_object_list
|
|
68
67
|
|
|
@@ -84,7 +83,7 @@ class SSHKeysService:
|
|
|
84
83
|
:param id_list: list of SSH keys ids
|
|
85
84
|
:type id_list: List[str]
|
|
86
85
|
"""
|
|
87
|
-
payload = {
|
|
86
|
+
payload = {'keys': id_list}
|
|
88
87
|
self._http_client.delete(SSHKEYS_ENDPOINT, json=payload)
|
|
89
88
|
return
|
|
90
89
|
|
|
@@ -107,6 +106,6 @@ class SSHKeysService:
|
|
|
107
106
|
:return: new SSH key object
|
|
108
107
|
:rtype: SSHKey
|
|
109
108
|
"""
|
|
110
|
-
payload = {
|
|
109
|
+
payload = {'name': name, 'key': key}
|
|
111
110
|
id = self._http_client.post(SSHKEYS_ENDPOINT, json=payload).text
|
|
112
111
|
return SSHKey(id, name, key)
|
|
@@ -61,8 +61,12 @@ class StartupScriptsService:
|
|
|
61
61
|
:rtype: List[StartupScript]
|
|
62
62
|
"""
|
|
63
63
|
scripts = self._http_client.get(STARTUP_SCRIPTS_ENDPOINT).json()
|
|
64
|
-
scripts_objects = list(
|
|
65
|
-
|
|
64
|
+
scripts_objects = list(
|
|
65
|
+
map(
|
|
66
|
+
lambda script: StartupScript(script['id'], script['name'], script['script']),
|
|
67
|
+
scripts,
|
|
68
|
+
)
|
|
69
|
+
)
|
|
66
70
|
return scripts_objects
|
|
67
71
|
|
|
68
72
|
def get_by_id(self, id) -> StartupScript:
|
|
@@ -73,8 +77,7 @@ class StartupScriptsService:
|
|
|
73
77
|
:return: startup script object
|
|
74
78
|
:rtype: StartupScript
|
|
75
79
|
"""
|
|
76
|
-
script = self._http_client.get(
|
|
77
|
-
STARTUP_SCRIPTS_ENDPOINT + f'/{id}').json()[0]
|
|
80
|
+
script = self._http_client.get(STARTUP_SCRIPTS_ENDPOINT + f'/{id}').json()[0]
|
|
78
81
|
|
|
79
82
|
return StartupScript(script['id'], script['name'], script['script'])
|
|
80
83
|
|
|
@@ -84,7 +87,7 @@ class StartupScriptsService:
|
|
|
84
87
|
:param id_list: list of startup scripts ids
|
|
85
88
|
:type id_list: List[str]
|
|
86
89
|
"""
|
|
87
|
-
payload = {
|
|
90
|
+
payload = {'scripts': id_list}
|
|
88
91
|
self._http_client.delete(STARTUP_SCRIPTS_ENDPOINT, json=payload)
|
|
89
92
|
return
|
|
90
93
|
|
|
@@ -107,7 +110,6 @@ class StartupScriptsService:
|
|
|
107
110
|
:return: the new startup script's id
|
|
108
111
|
:rtype: str
|
|
109
112
|
"""
|
|
110
|
-
payload = {
|
|
111
|
-
id = self._http_client.post(
|
|
112
|
-
STARTUP_SCRIPTS_ENDPOINT, json=payload).text
|
|
113
|
+
payload = {'name': name, 'script': script}
|
|
114
|
+
id = self._http_client.post(STARTUP_SCRIPTS_ENDPOINT, json=payload).text
|
|
113
115
|
return StartupScript(id, name, script)
|
|
@@ -4,10 +4,7 @@ VOLUME_TYPES_ENDPOINT = '/volume-types'
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class VolumeType:
|
|
7
|
-
|
|
8
|
-
def __init__(self,
|
|
9
|
-
type: str,
|
|
10
|
-
price_per_month_per_gb: float) -> None:
|
|
7
|
+
def __init__(self, type: str, price_per_month_per_gb: float) -> None:
|
|
11
8
|
"""Initialize a volume type object
|
|
12
9
|
|
|
13
10
|
:param type: volume type name
|
|
@@ -58,9 +55,14 @@ class VolumeTypesService:
|
|
|
58
55
|
:rtype: List[VolumesType]
|
|
59
56
|
"""
|
|
60
57
|
volume_types = self._http_client.get(VOLUME_TYPES_ENDPOINT).json()
|
|
61
|
-
volume_type_objects = list(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
volume_type_objects = list(
|
|
59
|
+
map(
|
|
60
|
+
lambda volume_type: VolumeType(
|
|
61
|
+
type=volume_type['type'],
|
|
62
|
+
price_per_month_per_gb=volume_type['price']['price_per_month_per_gb'],
|
|
63
|
+
),
|
|
64
|
+
volume_types,
|
|
65
|
+
)
|
|
66
|
+
)
|
|
65
67
|
|
|
66
68
|
return volume_type_objects
|