datacrunch 1.15.0__py3-none-any.whl → 1.17.1__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/__init__.py +53 -1
- datacrunch/datacrunch.py +44 -81
- datacrunch-1.17.1.dist-info/METADATA +30 -0
- datacrunch-1.17.1.dist-info/RECORD +5 -0
- datacrunch-1.17.1.dist-info/WHEEL +4 -0
- datacrunch/InferenceClient/__init__.py +0 -3
- datacrunch/InferenceClient/inference_client.py +0 -379
- datacrunch/__version__.py +0 -1
- datacrunch/authentication/__init__.py +0 -0
- datacrunch/authentication/authentication.py +0 -112
- datacrunch/balance/__init__.py +0 -0
- datacrunch/balance/balance.py +0 -52
- datacrunch/constants.py +0 -107
- datacrunch/containers/__init__.py +0 -33
- datacrunch/containers/containers.py +0 -1081
- datacrunch/exceptions.py +0 -29
- datacrunch/helpers.py +0 -13
- datacrunch/http_client/__init__.py +0 -0
- datacrunch/http_client/http_client.py +0 -241
- datacrunch/images/__init__.py +0 -0
- datacrunch/images/images.py +0 -87
- datacrunch/instance_types/__init__.py +0 -0
- datacrunch/instance_types/instance_types.py +0 -188
- datacrunch/instances/__init__.py +0 -0
- datacrunch/instances/instances.py +0 -247
- datacrunch/locations/__init__.py +0 -0
- datacrunch/locations/locations.py +0 -16
- datacrunch/ssh_keys/__init__.py +0 -0
- datacrunch/ssh_keys/ssh_keys.py +0 -112
- datacrunch/startup_scripts/__init__.py +0 -0
- datacrunch/startup_scripts/startup_scripts.py +0 -113
- datacrunch/volume_types/__init__.py +0 -0
- datacrunch/volume_types/volume_types.py +0 -66
- datacrunch/volumes/__init__.py +0 -0
- datacrunch/volumes/volumes.py +0 -398
- datacrunch-1.15.0.dist-info/METADATA +0 -208
- 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
datacrunch/exceptions.py
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
class APIException(Exception):
|
|
2
|
-
"""This exception is raised if there was an error from datacrunch's API.
|
|
3
|
-
Could be an invalid input, token etc.
|
|
4
|
-
|
|
5
|
-
Raised when an API HTTP call response has a status code >= 400
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
def __init__(self, code: str, message: str) -> None:
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
:param code: error code
|
|
12
|
-
:type code: str
|
|
13
|
-
:param message: error message
|
|
14
|
-
:type message: str
|
|
15
|
-
"""
|
|
16
|
-
self.code = code
|
|
17
|
-
"""Error code. should be available in DataCrunchClient.error_codes"""
|
|
18
|
-
|
|
19
|
-
self.message = message
|
|
20
|
-
"""Error message
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
def __str__(self) -> str:
|
|
24
|
-
msg = ''
|
|
25
|
-
if self.code:
|
|
26
|
-
msg = f'error code: {self.code}\n'
|
|
27
|
-
|
|
28
|
-
msg += f'message: {self.message}'
|
|
29
|
-
return msg
|
datacrunch/helpers.py
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
from typing import Type
|
|
2
|
-
import json
|
|
3
|
-
|
|
4
|
-
def stringify_class_object_properties(class_object: Type) -> str:
|
|
5
|
-
"""Generates a json string representation of a class object's properties and values
|
|
6
|
-
|
|
7
|
-
:param class_object: An instance of a class
|
|
8
|
-
:type class_object: Type
|
|
9
|
-
:return: _description_
|
|
10
|
-
:rtype: json string representation of a class object's properties and values
|
|
11
|
-
"""
|
|
12
|
-
class_properties = {property: getattr(class_object, property, '') for property in class_object.__dir__() if property[:1] != '_' and type(getattr(class_object, property, '')).__name__ != 'method'}
|
|
13
|
-
return json.dumps(class_properties, indent=2)
|
|
File without changes
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import requests
|
|
2
|
-
import json
|
|
3
|
-
|
|
4
|
-
from datacrunch.exceptions import APIException
|
|
5
|
-
from datacrunch.__version__ import VERSION
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def handle_error(response: requests.Response) -> None:
|
|
9
|
-
"""checks for the response status code and raises an exception if it's 400 or higher.
|
|
10
|
-
|
|
11
|
-
:param response: the API call response
|
|
12
|
-
:raises APIException: an api exception with message and error type code
|
|
13
|
-
"""
|
|
14
|
-
if not response.ok:
|
|
15
|
-
data = json.loads(response.text)
|
|
16
|
-
code = data['code'] if 'code' in data else None
|
|
17
|
-
message = data['message'] if 'message' in data else None
|
|
18
|
-
raise APIException(code, message)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class HTTPClient:
|
|
22
|
-
"""An http client, a wrapper for the requests library.
|
|
23
|
-
|
|
24
|
-
For each request, it adds the authentication header with an access token.
|
|
25
|
-
If the access token is expired it refreshes it before calling the specified API endpoint.
|
|
26
|
-
Also checks the response status code and raises an exception if needed.
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
def __init__(self, auth_service, base_url: str) -> None:
|
|
30
|
-
self._version = VERSION
|
|
31
|
-
self._base_url = base_url
|
|
32
|
-
self._auth_service = auth_service
|
|
33
|
-
self._auth_service.authenticate()
|
|
34
|
-
|
|
35
|
-
def post(self, url: str, json: dict = None, params: dict = None, **kwargs) -> requests.Response:
|
|
36
|
-
"""Sends a POST request.
|
|
37
|
-
|
|
38
|
-
A wrapper for the requests.post method.
|
|
39
|
-
|
|
40
|
-
Builds the url, uses custom headers, refresh tokens if needed.
|
|
41
|
-
|
|
42
|
-
:param url: relative url of the API endpoint
|
|
43
|
-
:type url: str
|
|
44
|
-
:param json: A JSON serializable Python object to send in the body of the Request, defaults to None
|
|
45
|
-
:type json: dict, optional
|
|
46
|
-
:param params: Dictionary of querystring data to attach to the Request, defaults to None
|
|
47
|
-
:type params: dict, optional
|
|
48
|
-
|
|
49
|
-
:raises APIException: an api exception with message and error type code
|
|
50
|
-
|
|
51
|
-
:return: Response object
|
|
52
|
-
:rtype: requests.Response
|
|
53
|
-
"""
|
|
54
|
-
self._refresh_token_if_expired()
|
|
55
|
-
|
|
56
|
-
url = self._add_base_url(url)
|
|
57
|
-
headers = self._generate_headers()
|
|
58
|
-
|
|
59
|
-
response = requests.post(
|
|
60
|
-
url, json=json, headers=headers, params=params, **kwargs)
|
|
61
|
-
handle_error(response)
|
|
62
|
-
|
|
63
|
-
return response
|
|
64
|
-
|
|
65
|
-
def put(self, url: str, json: dict = None, params: dict = None, **kwargs) -> requests.Response:
|
|
66
|
-
"""Sends a PUT request.
|
|
67
|
-
|
|
68
|
-
A wrapper for the requests.put method.
|
|
69
|
-
|
|
70
|
-
Builds the url, uses custom headers, refresh tokens if needed.
|
|
71
|
-
|
|
72
|
-
:param url: relative url of the API endpoint
|
|
73
|
-
:type url: str
|
|
74
|
-
:param json: A JSON serializable Python object to send in the body of the Request, defaults to None
|
|
75
|
-
:type json: dict, optional
|
|
76
|
-
:param params: Dictionary of querystring data to attach to the Request, defaults to None
|
|
77
|
-
:type params: dict, optional
|
|
78
|
-
|
|
79
|
-
:raises APIException: an api exception with message and error type code
|
|
80
|
-
|
|
81
|
-
:return: Response object
|
|
82
|
-
:rtype: requests.Response
|
|
83
|
-
"""
|
|
84
|
-
self._refresh_token_if_expired()
|
|
85
|
-
|
|
86
|
-
url = self._add_base_url(url)
|
|
87
|
-
headers = self._generate_headers()
|
|
88
|
-
|
|
89
|
-
response = requests.put(
|
|
90
|
-
url, json=json, headers=headers, params=params, **kwargs)
|
|
91
|
-
handle_error(response)
|
|
92
|
-
|
|
93
|
-
return response
|
|
94
|
-
|
|
95
|
-
def get(self, url: str, params: dict = None, **kwargs) -> requests.Response:
|
|
96
|
-
"""Sends a GET request.
|
|
97
|
-
|
|
98
|
-
A wrapper for the requests.get method.
|
|
99
|
-
|
|
100
|
-
Builds the url, uses custom headers, refresh tokens if needed.
|
|
101
|
-
|
|
102
|
-
:param url: relative url of the API endpoint
|
|
103
|
-
:type url: str
|
|
104
|
-
:param params: Dictionary of querystring data to attach to the Request, defaults to None
|
|
105
|
-
:type params: dict, optional
|
|
106
|
-
|
|
107
|
-
:raises APIException: an api exception with message and error type code
|
|
108
|
-
|
|
109
|
-
:return: Response object
|
|
110
|
-
:rtype: requests.Response
|
|
111
|
-
"""
|
|
112
|
-
self._refresh_token_if_expired()
|
|
113
|
-
|
|
114
|
-
url = self._add_base_url(url)
|
|
115
|
-
headers = self._generate_headers()
|
|
116
|
-
|
|
117
|
-
response = requests.get(url, params=params, headers=headers, **kwargs)
|
|
118
|
-
handle_error(response)
|
|
119
|
-
|
|
120
|
-
return response
|
|
121
|
-
|
|
122
|
-
def patch(self, url: str, json: dict = None, params: dict = None, **kwargs) -> requests.Response:
|
|
123
|
-
"""Sends a PATCH request.
|
|
124
|
-
|
|
125
|
-
A wrapper for the requests.patch method.
|
|
126
|
-
|
|
127
|
-
Builds the url, uses custom headers, refresh tokens if needed.
|
|
128
|
-
|
|
129
|
-
:param url: relative url of the API endpoint
|
|
130
|
-
:type url: str
|
|
131
|
-
:param json: A JSON serializable Python object to send in the body of the Request, defaults to None
|
|
132
|
-
:type json: dict, optional
|
|
133
|
-
:param params: Dictionary of querystring data to attach to the Request, defaults to None
|
|
134
|
-
:type params: dict, optional
|
|
135
|
-
|
|
136
|
-
:raises APIException: an api exception with message and error type code
|
|
137
|
-
|
|
138
|
-
:return: Response object
|
|
139
|
-
:rtype: requests.Response
|
|
140
|
-
"""
|
|
141
|
-
self._refresh_token_if_expired()
|
|
142
|
-
|
|
143
|
-
url = self._add_base_url(url)
|
|
144
|
-
headers = self._generate_headers()
|
|
145
|
-
|
|
146
|
-
response = requests.patch(
|
|
147
|
-
url, json=json, headers=headers, params=params, **kwargs)
|
|
148
|
-
handle_error(response)
|
|
149
|
-
|
|
150
|
-
return response
|
|
151
|
-
|
|
152
|
-
def delete(self, url: str, json: dict = None, params: dict = None, **kwargs) -> requests.Response:
|
|
153
|
-
"""Sends a DELETE request.
|
|
154
|
-
|
|
155
|
-
A wrapper for the requests.delete method.
|
|
156
|
-
|
|
157
|
-
Builds the url, uses custom headers, refresh tokens if needed.
|
|
158
|
-
|
|
159
|
-
:param url: relative url of the API endpoint
|
|
160
|
-
:type url: str
|
|
161
|
-
:param json: A JSON serializable Python object to send in the body of the Request, defaults to None
|
|
162
|
-
:type json: dict, optional
|
|
163
|
-
:param params: Dictionary of querystring data to attach to the Request, defaults to None
|
|
164
|
-
:type params: dict, optional
|
|
165
|
-
|
|
166
|
-
:raises APIException: an api exception with message and error type code
|
|
167
|
-
|
|
168
|
-
:return: Response object
|
|
169
|
-
:rtype: requests.Response
|
|
170
|
-
"""
|
|
171
|
-
self._refresh_token_if_expired()
|
|
172
|
-
|
|
173
|
-
url = self._add_base_url(url)
|
|
174
|
-
headers = self._generate_headers()
|
|
175
|
-
|
|
176
|
-
response = requests.delete(
|
|
177
|
-
url, headers=headers, json=json, params=params, **kwargs)
|
|
178
|
-
handle_error(response)
|
|
179
|
-
|
|
180
|
-
return response
|
|
181
|
-
|
|
182
|
-
def _refresh_token_if_expired(self) -> None:
|
|
183
|
-
"""refreshes the access token if it expired.
|
|
184
|
-
|
|
185
|
-
Uses the refresh token to refresh, and if the refresh token is also expired, uses the client credentials.
|
|
186
|
-
|
|
187
|
-
:raises APIException: an api exception with message and error type code
|
|
188
|
-
"""
|
|
189
|
-
if (self._auth_service.is_expired()):
|
|
190
|
-
# try to refresh. if refresh token has expired, reauthenticate
|
|
191
|
-
try:
|
|
192
|
-
self._auth_service.refresh()
|
|
193
|
-
except Exception:
|
|
194
|
-
self._auth_service.authenticate()
|
|
195
|
-
|
|
196
|
-
def _generate_headers(self) -> dict:
|
|
197
|
-
"""generate the default headers for every request
|
|
198
|
-
|
|
199
|
-
:return: dict with request headers
|
|
200
|
-
:rtype: dict
|
|
201
|
-
"""
|
|
202
|
-
headers = {
|
|
203
|
-
'Authorization': self._generate_bearer_header(),
|
|
204
|
-
'User-Agent': self._generate_user_agent(),
|
|
205
|
-
'Content-Type': 'application/json'
|
|
206
|
-
}
|
|
207
|
-
return headers
|
|
208
|
-
|
|
209
|
-
def _generate_bearer_header(self) -> str:
|
|
210
|
-
"""generate the authorization header Bearer string
|
|
211
|
-
|
|
212
|
-
:return: Authorization header Bearer string
|
|
213
|
-
:rtype: str
|
|
214
|
-
"""
|
|
215
|
-
return f'Bearer {self._auth_service._access_token}'
|
|
216
|
-
|
|
217
|
-
def _generate_user_agent(self) -> str:
|
|
218
|
-
"""generate the user agent string.
|
|
219
|
-
|
|
220
|
-
:return: user agent string
|
|
221
|
-
:rtype: str
|
|
222
|
-
"""
|
|
223
|
-
# get the first 10 chars of the client id
|
|
224
|
-
client_id_truncated = self._auth_service._client_id[:10]
|
|
225
|
-
|
|
226
|
-
return f'datacrunch-python-v{self._version}-{client_id_truncated}'
|
|
227
|
-
|
|
228
|
-
def _add_base_url(self, url: str) -> str:
|
|
229
|
-
"""Adds the base url to the relative url
|
|
230
|
-
|
|
231
|
-
example:
|
|
232
|
-
if the relative url is '/balance'
|
|
233
|
-
and the base url is 'https://api.datacrunch.io/v1'
|
|
234
|
-
then this method will return 'https://api.datacrunch.io/v1/balance'
|
|
235
|
-
|
|
236
|
-
:param url: a relative url path
|
|
237
|
-
:type url: str
|
|
238
|
-
:return: the full url path
|
|
239
|
-
:rtype: str
|
|
240
|
-
"""
|
|
241
|
-
return self._base_url + url
|
datacrunch/images/__init__.py
DELETED
|
File without changes
|
datacrunch/images/images.py
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
from datacrunch.helpers import stringify_class_object_properties
|
|
3
|
-
|
|
4
|
-
IMAGES_ENDPOINT = '/images'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class Image:
|
|
8
|
-
"""An image model class"""
|
|
9
|
-
|
|
10
|
-
def __init__(self, id: str, name: str, image_type: str, details: List[str]) -> None:
|
|
11
|
-
"""Initialize an image object
|
|
12
|
-
|
|
13
|
-
:param id: image id
|
|
14
|
-
:type id: str
|
|
15
|
-
:param name: image name
|
|
16
|
-
:type name: str
|
|
17
|
-
:param image_type: image type, e.g. 'ubuntu-20.04-cuda-11.0'
|
|
18
|
-
:type image_type: str
|
|
19
|
-
:param details: image details
|
|
20
|
-
:type details: List[str]
|
|
21
|
-
"""
|
|
22
|
-
self._id = id
|
|
23
|
-
self._name = name
|
|
24
|
-
self._image_type = image_type
|
|
25
|
-
self._details = details
|
|
26
|
-
|
|
27
|
-
@property
|
|
28
|
-
def id(self) -> str:
|
|
29
|
-
"""Get the image id
|
|
30
|
-
|
|
31
|
-
:return: image id
|
|
32
|
-
:rtype: str
|
|
33
|
-
"""
|
|
34
|
-
return self._id
|
|
35
|
-
|
|
36
|
-
@property
|
|
37
|
-
def name(self) -> str:
|
|
38
|
-
"""Get the image name
|
|
39
|
-
|
|
40
|
-
:return: image name
|
|
41
|
-
:rtype: str
|
|
42
|
-
"""
|
|
43
|
-
return self._name
|
|
44
|
-
|
|
45
|
-
@property
|
|
46
|
-
def image_type(self) -> str:
|
|
47
|
-
"""Get the image type
|
|
48
|
-
|
|
49
|
-
:return: image type
|
|
50
|
-
:rtype: str
|
|
51
|
-
"""
|
|
52
|
-
return self._image_type
|
|
53
|
-
|
|
54
|
-
@property
|
|
55
|
-
def details(self) -> List[str]:
|
|
56
|
-
"""Get the image details
|
|
57
|
-
|
|
58
|
-
:return: image details
|
|
59
|
-
:rtype: List[str]
|
|
60
|
-
"""
|
|
61
|
-
return self._details
|
|
62
|
-
|
|
63
|
-
def __str__(self) -> str:
|
|
64
|
-
"""Returns a string of the json representation of the image
|
|
65
|
-
|
|
66
|
-
:return: json representation of the image
|
|
67
|
-
:rtype: str
|
|
68
|
-
"""
|
|
69
|
-
return stringify_class_object_properties(self)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
class ImagesService:
|
|
73
|
-
"""A service for interacting with the images endpoint"""
|
|
74
|
-
|
|
75
|
-
def __init__(self, http_client) -> None:
|
|
76
|
-
self._http_client = http_client
|
|
77
|
-
|
|
78
|
-
def get(self) -> List[Image]:
|
|
79
|
-
"""Get the available instance images
|
|
80
|
-
|
|
81
|
-
:return: list of images objects
|
|
82
|
-
:rtype: List[Image]
|
|
83
|
-
"""
|
|
84
|
-
images = self._http_client.get(IMAGES_ENDPOINT).json()
|
|
85
|
-
image_objects = list(map(lambda image: Image(
|
|
86
|
-
image['id'], image['name'], image['image_type'], image['details']), images))
|
|
87
|
-
return image_objects
|
|
File without changes
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
|
|
3
|
-
INSTANCE_TYPES_ENDPOINT = '/instance-types'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class InstanceType:
|
|
7
|
-
|
|
8
|
-
def __init__(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) -> None:
|
|
19
|
-
"""Initialize an instance type object
|
|
20
|
-
|
|
21
|
-
:param id: instance type id
|
|
22
|
-
:type id: str
|
|
23
|
-
:param instance_type: instance type. e.g. '8V100.48M'
|
|
24
|
-
:type instance_type: str
|
|
25
|
-
:param price_per_hour: price per hour
|
|
26
|
-
:type price_per_hour: float
|
|
27
|
-
:param spot_price_per_hour: spot price per hour
|
|
28
|
-
:type spot_price_per_hour: float
|
|
29
|
-
:param description: instance type description
|
|
30
|
-
:type description: str
|
|
31
|
-
:param cpu: cpu details
|
|
32
|
-
:type cpu: dict
|
|
33
|
-
:param gpu: gpu details
|
|
34
|
-
:type gpu: dict
|
|
35
|
-
:param memory: memory details
|
|
36
|
-
:type memory: dict
|
|
37
|
-
:param gpu_memory: gpu memory details
|
|
38
|
-
:type gpu_memory: dict
|
|
39
|
-
:param storage: storage details
|
|
40
|
-
:type storage: dict
|
|
41
|
-
"""
|
|
42
|
-
self._id = id
|
|
43
|
-
self._instance_type = instance_type
|
|
44
|
-
self._price_per_hour = float(price_per_hour)
|
|
45
|
-
self._spot_price_per_hour = float(spot_price_per_hour)
|
|
46
|
-
self._description = description
|
|
47
|
-
self._cpu = cpu
|
|
48
|
-
self._gpu = gpu
|
|
49
|
-
self._memory = memory
|
|
50
|
-
self._gpu_memory = gpu_memory
|
|
51
|
-
self._storage = storage
|
|
52
|
-
|
|
53
|
-
@property
|
|
54
|
-
def id(self) -> str:
|
|
55
|
-
"""Get the instance type id
|
|
56
|
-
|
|
57
|
-
:return: instance type id
|
|
58
|
-
:rtype: str
|
|
59
|
-
"""
|
|
60
|
-
return self._id
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def instance_type(self) -> str:
|
|
64
|
-
"""Get the instance type
|
|
65
|
-
|
|
66
|
-
:return: instance type. e.g. '8V100.48M'
|
|
67
|
-
:rtype: str
|
|
68
|
-
"""
|
|
69
|
-
return self._instance_type
|
|
70
|
-
|
|
71
|
-
@property
|
|
72
|
-
def price_per_hour(self) -> float:
|
|
73
|
-
"""Get the instance type price per hour
|
|
74
|
-
|
|
75
|
-
:return: price per hour
|
|
76
|
-
:rtype: float
|
|
77
|
-
"""
|
|
78
|
-
return self._price_per_hour
|
|
79
|
-
|
|
80
|
-
@property
|
|
81
|
-
def spot_price_per_hour(self) -> float:
|
|
82
|
-
"""Get the instance spot price per hour
|
|
83
|
-
|
|
84
|
-
:return: spot price per hour
|
|
85
|
-
:rtype: float
|
|
86
|
-
"""
|
|
87
|
-
return self._spot_price_per_hour
|
|
88
|
-
|
|
89
|
-
@property
|
|
90
|
-
def description(self) -> str:
|
|
91
|
-
"""Get the instance type description
|
|
92
|
-
|
|
93
|
-
:return: instance type description
|
|
94
|
-
:rtype: str
|
|
95
|
-
"""
|
|
96
|
-
return self._description
|
|
97
|
-
|
|
98
|
-
@property
|
|
99
|
-
def cpu(self) -> dict:
|
|
100
|
-
"""Get the instance type cpu details
|
|
101
|
-
|
|
102
|
-
:return: cpu details
|
|
103
|
-
:rtype: dict
|
|
104
|
-
"""
|
|
105
|
-
return self._cpu
|
|
106
|
-
|
|
107
|
-
@property
|
|
108
|
-
def gpu(self) -> dict:
|
|
109
|
-
"""Get the instance type gpu details
|
|
110
|
-
|
|
111
|
-
:return: gpu details
|
|
112
|
-
:rtype: dict
|
|
113
|
-
"""
|
|
114
|
-
return self._gpu
|
|
115
|
-
|
|
116
|
-
@property
|
|
117
|
-
def memory(self) -> dict:
|
|
118
|
-
"""Get the instance type memory details
|
|
119
|
-
|
|
120
|
-
:return: memory details
|
|
121
|
-
:rtype: dict
|
|
122
|
-
"""
|
|
123
|
-
return self._memory
|
|
124
|
-
|
|
125
|
-
@property
|
|
126
|
-
def gpu_memory(self) -> dict:
|
|
127
|
-
"""Get the instance type gpu_memory details
|
|
128
|
-
|
|
129
|
-
:return: gpu_memory details
|
|
130
|
-
:rtype: dict
|
|
131
|
-
"""
|
|
132
|
-
return self._gpu_memory
|
|
133
|
-
|
|
134
|
-
@property
|
|
135
|
-
def storage(self) -> dict:
|
|
136
|
-
"""Get the instance type storage details
|
|
137
|
-
|
|
138
|
-
:return: storage details
|
|
139
|
-
:rtype: dict
|
|
140
|
-
"""
|
|
141
|
-
return self._storage
|
|
142
|
-
|
|
143
|
-
def __str__(self) -> str:
|
|
144
|
-
"""Prints the instance type
|
|
145
|
-
|
|
146
|
-
:return: instance type string representation
|
|
147
|
-
:rtype: str
|
|
148
|
-
"""
|
|
149
|
-
return (f'id: {self._id}\n'
|
|
150
|
-
f'instance type: {self._instance_type}\n'
|
|
151
|
-
f'price_per_hour: ${self._price_per_hour}\n'
|
|
152
|
-
f'spot_price_per_hour: ${self._spot_price_per_hour}\n'
|
|
153
|
-
f'description: {self._description}\n'
|
|
154
|
-
f'cpu: {self._cpu}\n'
|
|
155
|
-
f'gpu: {self._gpu}\n'
|
|
156
|
-
f'memory :{self._memory}\n'
|
|
157
|
-
f'gpu_memory :{self._gpu_memory}\n'
|
|
158
|
-
f'storage :{self._storage}\n'
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
class InstanceTypesService:
|
|
163
|
-
"""A service for interacting with the instance-types endpoint"""
|
|
164
|
-
|
|
165
|
-
def __init__(self, http_client) -> None:
|
|
166
|
-
self._http_client = http_client
|
|
167
|
-
|
|
168
|
-
def get(self) -> List[InstanceType]:
|
|
169
|
-
"""Get all instance types
|
|
170
|
-
|
|
171
|
-
:return: list of instance type objects
|
|
172
|
-
:rtype: List[InstanceType]
|
|
173
|
-
"""
|
|
174
|
-
instance_types = self._http_client.get(INSTANCE_TYPES_ENDPOINT).json()
|
|
175
|
-
instance_type_objects = list(map(lambda instance_type: InstanceType(
|
|
176
|
-
id=instance_type['id'],
|
|
177
|
-
instance_type=instance_type['instance_type'],
|
|
178
|
-
price_per_hour=instance_type['price_per_hour'],
|
|
179
|
-
spot_price_per_hour=instance_type['spot_price'],
|
|
180
|
-
description=instance_type['description'],
|
|
181
|
-
cpu=instance_type['cpu'],
|
|
182
|
-
gpu=instance_type['gpu'],
|
|
183
|
-
memory=instance_type['memory'],
|
|
184
|
-
gpu_memory=instance_type['gpu_memory'],
|
|
185
|
-
storage=instance_type['storage']
|
|
186
|
-
), instance_types))
|
|
187
|
-
|
|
188
|
-
return instance_type_objects
|
datacrunch/instances/__init__.py
DELETED
|
File without changes
|