datacrunch 1.16.0__py3-none-any.whl → 1.17.2__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 (49) hide show
  1. datacrunch/InferenceClient/__init__.py +1 -1
  2. datacrunch/InferenceClient/inference_client.py +1 -514
  3. datacrunch/__init__.py +52 -2
  4. datacrunch/authentication.py +1 -0
  5. datacrunch/balance.py +1 -0
  6. datacrunch/constants.py +1 -109
  7. datacrunch/containers.py +1 -0
  8. datacrunch/datacrunch.py +44 -81
  9. datacrunch/exceptions.py +1 -29
  10. datacrunch/helpers.py +1 -18
  11. datacrunch/http_client.py +1 -0
  12. datacrunch/images.py +1 -0
  13. datacrunch/instance_types.py +1 -0
  14. datacrunch/instances.py +1 -0
  15. datacrunch/locations.py +1 -0
  16. datacrunch/ssh_keys.py +1 -0
  17. datacrunch/startup_scripts.py +1 -0
  18. datacrunch/volume_types.py +1 -0
  19. datacrunch/volumes.py +1 -0
  20. datacrunch-1.17.2.dist-info/METADATA +30 -0
  21. datacrunch-1.17.2.dist-info/RECORD +22 -0
  22. {datacrunch-1.16.0.dist-info → datacrunch-1.17.2.dist-info}/WHEEL +1 -1
  23. datacrunch/_version.py +0 -6
  24. datacrunch/authentication/__init__.py +0 -0
  25. datacrunch/authentication/authentication.py +0 -105
  26. datacrunch/balance/__init__.py +0 -0
  27. datacrunch/balance/balance.py +0 -50
  28. datacrunch/containers/__init__.py +0 -33
  29. datacrunch/containers/containers.py +0 -1109
  30. datacrunch/http_client/__init__.py +0 -0
  31. datacrunch/http_client/http_client.py +0 -241
  32. datacrunch/images/__init__.py +0 -0
  33. datacrunch/images/images.py +0 -93
  34. datacrunch/instance_types/__init__.py +0 -0
  35. datacrunch/instance_types/instance_types.py +0 -195
  36. datacrunch/instances/__init__.py +0 -0
  37. datacrunch/instances/instances.py +0 -259
  38. datacrunch/locations/__init__.py +0 -0
  39. datacrunch/locations/locations.py +0 -15
  40. datacrunch/ssh_keys/__init__.py +0 -0
  41. datacrunch/ssh_keys/ssh_keys.py +0 -111
  42. datacrunch/startup_scripts/__init__.py +0 -0
  43. datacrunch/startup_scripts/startup_scripts.py +0 -115
  44. datacrunch/volume_types/__init__.py +0 -0
  45. datacrunch/volume_types/volume_types.py +0 -68
  46. datacrunch/volumes/__init__.py +0 -0
  47. datacrunch/volumes/volumes.py +0 -385
  48. datacrunch-1.16.0.dist-info/METADATA +0 -182
  49. datacrunch-1.16.0.dist-info/RECORD +0 -35
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(url, json=json, headers=headers, params=params, **kwargs)
60
- handle_error(response)
61
-
62
- return response
63
-
64
- def put(self, url: str, json: dict = None, params: dict = None, **kwargs) -> requests.Response:
65
- """Sends a PUT request.
66
-
67
- A wrapper for the requests.put method.
68
-
69
- Builds the url, uses custom headers, refresh tokens if needed.
70
-
71
- :param url: relative url of the API endpoint
72
- :type url: str
73
- :param json: A JSON serializable Python object to send in the body of the Request, defaults to None
74
- :type json: dict, optional
75
- :param params: Dictionary of querystring data to attach to the Request, defaults to None
76
- :type params: dict, optional
77
-
78
- :raises APIException: an api exception with message and error type code
79
-
80
- :return: Response object
81
- :rtype: requests.Response
82
- """
83
- self._refresh_token_if_expired()
84
-
85
- url = self._add_base_url(url)
86
- headers = self._generate_headers()
87
-
88
- response = requests.put(url, json=json, headers=headers, params=params, **kwargs)
89
- handle_error(response)
90
-
91
- return response
92
-
93
- def get(self, url: str, params: dict = None, **kwargs) -> requests.Response:
94
- """Sends a GET request.
95
-
96
- A wrapper for the requests.get method.
97
-
98
- Builds the url, uses custom headers, refresh tokens if needed.
99
-
100
- :param url: relative url of the API endpoint
101
- :type url: str
102
- :param params: Dictionary of querystring data to attach to the Request, defaults to None
103
- :type params: dict, optional
104
-
105
- :raises APIException: an api exception with message and error type code
106
-
107
- :return: Response object
108
- :rtype: requests.Response
109
- """
110
- self._refresh_token_if_expired()
111
-
112
- url = self._add_base_url(url)
113
- headers = self._generate_headers()
114
-
115
- response = requests.get(url, params=params, headers=headers, **kwargs)
116
- handle_error(response)
117
-
118
- return response
119
-
120
- def patch(
121
- self, url: str, json: dict = None, params: dict = None, **kwargs
122
- ) -> 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(url, json=json, headers=headers, params=params, **kwargs)
147
- handle_error(response)
148
-
149
- return response
150
-
151
- def delete(
152
- self, url: str, json: dict = None, params: dict = None, **kwargs
153
- ) -> requests.Response:
154
- """Sends a DELETE request.
155
-
156
- A wrapper for the requests.delete method.
157
-
158
- Builds the url, uses custom headers, refresh tokens if needed.
159
-
160
- :param url: relative url of the API endpoint
161
- :type url: str
162
- :param json: A JSON serializable Python object to send in the body of the Request, defaults to None
163
- :type json: dict, optional
164
- :param params: Dictionary of querystring data to attach to the Request, defaults to None
165
- :type params: dict, optional
166
-
167
- :raises APIException: an api exception with message and error type code
168
-
169
- :return: Response object
170
- :rtype: requests.Response
171
- """
172
- self._refresh_token_if_expired()
173
-
174
- url = self._add_base_url(url)
175
- headers = self._generate_headers()
176
-
177
- response = requests.delete(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
File without changes
@@ -1,93 +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(
86
- map(
87
- lambda image: Image(
88
- image['id'], image['name'], image['image_type'], image['details']
89
- ),
90
- images,
91
- )
92
- )
93
- return image_objects
File without changes
@@ -1,195 +0,0 @@
1
- from typing import List
2
-
3
- INSTANCE_TYPES_ENDPOINT = '/instance-types'
4
-
5
-
6
- class InstanceType:
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:
20
- """Initialize an instance type object
21
-
22
- :param id: instance type id
23
- :type id: str
24
- :param instance_type: instance type. e.g. '8V100.48M'
25
- :type instance_type: str
26
- :param price_per_hour: price per hour
27
- :type price_per_hour: float
28
- :param spot_price_per_hour: spot price per hour
29
- :type spot_price_per_hour: float
30
- :param description: instance type description
31
- :type description: str
32
- :param cpu: cpu details
33
- :type cpu: dict
34
- :param gpu: gpu details
35
- :type gpu: dict
36
- :param memory: memory details
37
- :type memory: dict
38
- :param gpu_memory: gpu memory details
39
- :type gpu_memory: dict
40
- :param storage: storage details
41
- :type storage: dict
42
- """
43
- self._id = id
44
- self._instance_type = instance_type
45
- self._price_per_hour = float(price_per_hour)
46
- self._spot_price_per_hour = float(spot_price_per_hour)
47
- self._description = description
48
- self._cpu = cpu
49
- self._gpu = gpu
50
- self._memory = memory
51
- self._gpu_memory = gpu_memory
52
- self._storage = storage
53
-
54
- @property
55
- def id(self) -> str:
56
- """Get the instance type id
57
-
58
- :return: instance type id
59
- :rtype: str
60
- """
61
- return self._id
62
-
63
- @property
64
- def instance_type(self) -> str:
65
- """Get the instance type
66
-
67
- :return: instance type. e.g. '8V100.48M'
68
- :rtype: str
69
- """
70
- return self._instance_type
71
-
72
- @property
73
- def price_per_hour(self) -> float:
74
- """Get the instance type price per hour
75
-
76
- :return: price per hour
77
- :rtype: float
78
- """
79
- return self._price_per_hour
80
-
81
- @property
82
- def spot_price_per_hour(self) -> float:
83
- """Get the instance spot price per hour
84
-
85
- :return: spot price per hour
86
- :rtype: float
87
- """
88
- return self._spot_price_per_hour
89
-
90
- @property
91
- def description(self) -> str:
92
- """Get the instance type description
93
-
94
- :return: instance type description
95
- :rtype: str
96
- """
97
- return self._description
98
-
99
- @property
100
- def cpu(self) -> dict:
101
- """Get the instance type cpu details
102
-
103
- :return: cpu details
104
- :rtype: dict
105
- """
106
- return self._cpu
107
-
108
- @property
109
- def gpu(self) -> dict:
110
- """Get the instance type gpu details
111
-
112
- :return: gpu details
113
- :rtype: dict
114
- """
115
- return self._gpu
116
-
117
- @property
118
- def memory(self) -> dict:
119
- """Get the instance type memory details
120
-
121
- :return: memory details
122
- :rtype: dict
123
- """
124
- return self._memory
125
-
126
- @property
127
- def gpu_memory(self) -> dict:
128
- """Get the instance type gpu_memory details
129
-
130
- :return: gpu_memory details
131
- :rtype: dict
132
- """
133
- return self._gpu_memory
134
-
135
- @property
136
- def storage(self) -> dict:
137
- """Get the instance type storage details
138
-
139
- :return: storage details
140
- :rtype: dict
141
- """
142
- return self._storage
143
-
144
- def __str__(self) -> str:
145
- """Prints the instance type
146
-
147
- :return: instance type string representation
148
- :rtype: str
149
- """
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
- )
162
-
163
-
164
- class InstanceTypesService:
165
- """A service for interacting with the instance-types endpoint"""
166
-
167
- def __init__(self, http_client) -> None:
168
- self._http_client = http_client
169
-
170
- def get(self) -> List[InstanceType]:
171
- """Get all instance types
172
-
173
- :return: list of instance type objects
174
- :rtype: List[InstanceType]
175
- """
176
- instance_types = self._http_client.get(INSTANCE_TYPES_ENDPOINT).json()
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
- )
194
-
195
- return instance_type_objects
File without changes