Skip to content

Commit e3ea940

Browse files
committed
use dataclasses and dataclasses_json for Instance
1 parent 88d9238 commit e3ea940

File tree

1 file changed

+30
-327
lines changed

1 file changed

+30
-327
lines changed

datacrunch/instances/instances.py

Lines changed: 30 additions & 327 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
from typing import List, Union, Optional, Dict, Literal
2+
from dataclasses import dataclass
3+
from dataclasses_json import dataclass_json
24
from datacrunch.helpers import stringify_class_object_properties
35
from datacrunch.constants import Locations
46

@@ -7,283 +9,33 @@
79
Contract = Literal['LONG_TERM', 'PAY_AS_YOU_GO', 'SPOT']
810
Pricing = Literal['DYNAMIC_PRICE', 'FIXED_PRICE']
911

12+
13+
@dataclass_json
14+
@dataclass
1015
class Instance:
1116
"""An instance model class"""
1217

13-
def __init__(self,
14-
id: str,
15-
instance_type: str,
16-
image: str,
17-
price_per_hour: float,
18-
hostname: str,
19-
description: str,
20-
ip: str,
21-
status: str,
22-
created_at: str,
23-
ssh_key_ids: List[str],
24-
cpu: dict,
25-
gpu: dict,
26-
memory: dict,
27-
storage: dict,
28-
os_volume_id: str,
29-
gpu_memory: dict,
30-
location: str = Locations.FIN_01,
31-
startup_script_id: str = None,
32-
is_spot: bool = False,
33-
contract: Contract = None,
34-
pricing: Pricing = None,
35-
) -> None:
36-
"""Initialize the instance object
37-
38-
:param id: instance id
39-
:type id: str
40-
:param instance_type: instance type. e.g. '8V100.48M'
41-
:type instance_type: str
42-
:param image: instance image type. e.g. 'ubuntu-20.04-cuda-11.0'
43-
:type image: str
44-
:param price_per_hour: price per hour
45-
:type price_per_hour: float
46-
:param hostname: instance hostname
47-
:type hostname: str
48-
:param description: instance description
49-
:type description: str
50-
:param ip: instance ip address
51-
:type ip: str
52-
:param status: instance current status, might be out of date if changed
53-
:type status: str
54-
:param created_at: the time the instance was deployed (UTC)
55-
:type created_at: str
56-
:param ssh_key_ids: list of ssh keys ids
57-
:type ssh_key_ids: List[str]
58-
:param cpu: cpu details
59-
:type cpu: dict
60-
:param gpu: gpu details
61-
:type gpu: dict
62-
:param memory: memory details
63-
:type memory: dict
64-
:param storage: storate details
65-
:type storage: dict
66-
:param id: main OS volume id
67-
:type id: str
68-
:param memory: gpu memory details
69-
:type memory: dict
70-
:param location: datacenter location, defaults to "FIN-01"
71-
:type location: str, optional
72-
:param startup_script_id: startup script id, defaults to None
73-
:type startup_script_id: str, optional
74-
:param is_spot: is this a spot instance, defaults to None
75-
:type is_spot: bool, optional
76-
"""
77-
self._id = id
78-
self._instance_type = instance_type
79-
self._image = image
80-
self._price_per_hour = price_per_hour
81-
self._location = location
82-
self._hostname = hostname
83-
self._description = description
84-
self._ip = ip
85-
self._status = status
86-
self._created_at = created_at
87-
self._ssh_key_ids = ssh_key_ids
88-
self._startup_script_id = startup_script_id
89-
self._cpu = cpu
90-
self._gpu = gpu
91-
self._memory = memory
92-
self._storage = storage
93-
self._os_volume_id = os_volume_id
94-
self._gpu_memory = gpu_memory
95-
self._is_spot = is_spot
96-
self._contract = contract
97-
self._pricing = pricing
98-
99-
@property
100-
def id(self) -> str:
101-
"""Get the instance id
102-
103-
:return: instance id
104-
:rtype: str
105-
"""
106-
return self._id
107-
108-
@property
109-
def instance_type(self) -> str:
110-
"""Get the instance type
111-
112-
:return: instance type
113-
:rtype: str
114-
"""
115-
return self._instance_type
116-
117-
@property
118-
def image(self) -> str:
119-
"""Get the instance image type
120-
121-
:return: instance image type
122-
:rtype: str
123-
"""
124-
return self._image
125-
126-
@property
127-
def price_per_hour(self) -> float:
128-
"""Get the instance price per hour
129-
130-
:return: price per hour
131-
:rtype: float
132-
"""
133-
return self._price_per_hour
134-
135-
@property
136-
def location(self) -> str:
137-
"""Get the instance datacenter location
138-
139-
:return: datacenter location
140-
:rtype: str
141-
"""
142-
return self._location
143-
144-
@property
145-
def hostname(self) -> str:
146-
"""Get the instance hostname
147-
148-
:return: hostname
149-
:rtype: str
150-
"""
151-
return self._hostname
152-
153-
@property
154-
def description(self) -> str:
155-
"""Get the instance description
156-
157-
:return: instance description
158-
:rtype: str
159-
"""
160-
return self._description
161-
162-
@property
163-
def ip(self) -> str:
164-
"""Get the instance ip address
165-
166-
:return: ip address
167-
:rtype: str
168-
"""
169-
return self._ip
170-
171-
@property
172-
def status(self) -> str:
173-
"""Get the current instance status. might be out of date if changed.
174-
175-
:return: instance status
176-
:rtype: str
177-
"""
178-
return self._status
179-
180-
@property
181-
def created_at(self) -> str:
182-
"""Get the time when the instance was deployed (UTC)
183-
184-
:return: time
185-
:rtype: str
186-
"""
187-
return self._created_at
188-
189-
@property
190-
def ssh_key_ids(self) -> List[str]:
191-
"""Get the SSH key IDs of the instance
192-
193-
:return: SSH key IDs
194-
:rtype: List[str]
195-
"""
196-
return self._ssh_key_ids
197-
198-
@property
199-
def startup_script_id(self) -> Union[str, None]:
200-
"""Get the startup script ID or None if the is no script
201-
202-
:return: startup script ID or None
203-
:rtype: Union[str, None]
204-
"""
205-
return self._startup_script_id
206-
207-
@property
208-
def cpu(self) -> dict:
209-
"""Get the instance cpu details
210-
211-
:return: cpu details
212-
:rtype: dict
213-
"""
214-
return self._cpu
215-
216-
@property
217-
def gpu(self) -> dict:
218-
"""Get the instance gpu details
219-
220-
:return: gpu details
221-
:rtype: dict
222-
"""
223-
return self._gpu
224-
225-
@property
226-
def memory(self) -> dict:
227-
"""Get the instance memory details
228-
229-
:return: memory details
230-
:rtype: dict
231-
"""
232-
return self._memory
233-
234-
@property
235-
def storage(self) -> dict:
236-
"""Get the instance storage details
237-
238-
:return: storage details
239-
:rtype: dict
240-
"""
241-
return self._storage
242-
243-
@property
244-
def os_volume_id(self) -> str:
245-
"""Get the main os volume id
246-
247-
:return: main os volume id
248-
:rtype: str
249-
"""
250-
return self._os_volume_id
251-
252-
@property
253-
def gpu_memory(self) -> dict:
254-
"""Get the instance gpu_memory details
255-
256-
:return: gpu_memory details
257-
:rtype: dict
258-
"""
259-
return self._gpu_memory
260-
261-
@property
262-
def is_spot(self) -> bool:
263-
"""Is this a spot instance
264-
265-
:return: is spot details
266-
:rtype: bool
267-
"""
268-
return self._is_spot
269-
270-
@property
271-
def contract(self) -> bool:
272-
"""Get contract type
273-
274-
:return: contract type
275-
:rtype: str
276-
"""
277-
return self._contract
278-
279-
@property
280-
def pricing(self) -> bool:
281-
"""Get pricing type
282-
283-
:return: pricing type
284-
:rtype: str
285-
"""
286-
return self._pricing
18+
id: str
19+
instance_type: str
20+
price_per_hour: float
21+
hostname: str
22+
description: str
23+
ip: str
24+
status: str
25+
created_at: str
26+
ssh_key_ids: List[str]
27+
cpu: dict
28+
gpu: dict
29+
memory: dict
30+
storage: dict
31+
os_volume_id: str
32+
gpu_memory: dict
33+
location: str = Locations.FIN_01
34+
image: Optional[str] = None
35+
startup_script_id: Optional[str] = None
36+
is_spot: bool = False
37+
contract: Optional[Contract] = None
38+
pricing: Optional[Pricing] = None
28739

28840
def __str__(self) -> str:
28941
"""Returns a string of the json representation of the instance
@@ -310,31 +62,7 @@ def get(self, status: str = None) -> List[Instance]:
31062
"""
31163
instances_dict = self._http_client.get(
31264
INSTANCES_ENDPOINT, params={'status': status}).json()
313-
instances = list(map(lambda instance_dict: Instance(
314-
id=instance_dict['id'],
315-
instance_type=instance_dict['instance_type'],
316-
image=instance_dict['image'],
317-
price_per_hour=instance_dict['price_per_hour'] if 'price_per_hour' in instance_dict else None,
318-
location=instance_dict['location'],
319-
hostname=instance_dict['hostname'],
320-
description=instance_dict['description'],
321-
ip=instance_dict['ip'],
322-
status=instance_dict['status'],
323-
created_at=instance_dict['created_at'],
324-
ssh_key_ids=instance_dict['ssh_key_ids'] if 'ssh_key_ids' in instance_dict else [
325-
],
326-
startup_script_id=instance_dict['startup_script_id'] if 'startup_script_id' in instance_dict else None,
327-
cpu=instance_dict['cpu'],
328-
gpu=instance_dict['gpu'],
329-
memory=instance_dict['memory'],
330-
storage=instance_dict['storage'],
331-
os_volume_id=instance_dict['os_volume_id'] if 'os_volume_id' in instance_dict else None,
332-
gpu_memory=instance_dict['gpu_memory'] if 'gpu_memory' in instance_dict else None,
333-
is_spot=instance_dict['is_spot'] if 'is_spot' in instance_dict else False,
334-
contract=instance_dict['contract'] if 'contract' in instance_dict else False,
335-
pricing=instance_dict['pricing'] if 'pricing' in instance_dict else False,
336-
), instances_dict))
337-
return instances
65+
return [Instance.from_dict(instance_dict, infer_missing=True) for instance_dict in instances_dict]
33866

33967
def get_by_id(self, id: str) -> Instance:
34068
"""Get an instance with specified id.
@@ -346,31 +74,7 @@ def get_by_id(self, id: str) -> Instance:
34674
"""
34775
instance_dict = self._http_client.get(
34876
INSTANCES_ENDPOINT + f'/{id}').json()
349-
instance = Instance(
350-
id=instance_dict['id'],
351-
instance_type=instance_dict['instance_type'],
352-
image=instance_dict['image'],
353-
price_per_hour=instance_dict['price_per_hour'] if 'price_per_hour' in instance_dict else None,
354-
location=instance_dict['location'],
355-
hostname=instance_dict['hostname'],
356-
description=instance_dict['description'],
357-
ip=instance_dict['ip'],
358-
status=instance_dict['status'],
359-
created_at=instance_dict['created_at'],
360-
ssh_key_ids=instance_dict['ssh_key_ids'] if 'ssh_key_ids' in instance_dict else [
361-
],
362-
startup_script_id=instance_dict['startup_script_id'] if 'startup_script_id' in instance_dict else None,
363-
cpu=instance_dict['cpu'],
364-
gpu=instance_dict['gpu'],
365-
memory=instance_dict['memory'],
366-
storage=instance_dict['storage'],
367-
os_volume_id=instance_dict['os_volume_id'] if 'os_volume_id' in instance_dict else None,
368-
gpu_memory=instance_dict['gpu_memory'] if 'gpu_memory' in instance_dict else None,
369-
is_spot=instance_dict['is_spot'] if 'is_spot' in instance_dict else False,
370-
contract=instance_dict['contract'] if 'contract' in instance_dict else False,
371-
pricing=instance_dict['pricing'] if 'pricing' in instance_dict else False,
372-
)
373-
return instance
77+
return Instance.from_dict(instance_dict, infer_missing=True)
37478

37579
def create(self,
37680
instance_type: str,
@@ -418,7 +122,7 @@ def create(self,
418122
:param coupon: coupon code
419123
:type coupon: str, optional
420124
:return: the new instance object
421-
:rtype: id
125+
:rtype: Instance
422126
"""
423127
payload = {
424128
"instance_type": instance_type,
@@ -439,8 +143,7 @@ def create(self,
439143
if pricing:
440144
payload['pricing'] = pricing
441145
id = self._http_client.post(INSTANCES_ENDPOINT, json=payload).text
442-
instance = self.get_by_id(id)
443-
return instance
146+
return self.get_by_id(id)
444147

445148
def action(self, id_list: Union[List[str], str], action: str, volume_ids: Optional[List[str]] = None) -> None:
446149
"""Performs an action on a list of instances / single instance

0 commit comments

Comments
 (0)