11from typing import List , Union , Optional , Dict , Literal
2+ from dataclasses import dataclass
3+ from dataclasses_json import dataclass_json
24from datacrunch .helpers import stringify_class_object_properties
35from datacrunch .constants import Locations
46
79Contract = Literal ['LONG_TERM' , 'PAY_AS_YOU_GO' , 'SPOT' ]
810Pricing = Literal ['DYNAMIC_PRICE' , 'FIXED_PRICE' ]
911
12+
13+ @dataclass_json
14+ @dataclass
1015class 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