Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
singlestore-labs
GitHub Repository: singlestore-labs/singlestoredb-python
Path: blob/main/singlestoredb/management/inference_api.py
801 views
1
#!/usr/bin/env python
2
"""SingleStoreDB Cloud Inference API."""
3
import os
4
from typing import Any
5
from typing import Dict
6
from typing import List
7
from typing import Optional
8
9
from .utils import vars_to_str
10
from singlestoredb.exceptions import ManagementError
11
from singlestoredb.management.manager import Manager
12
13
14
class ModelOperationResult(object):
15
"""
16
Result of a model start or stop operation.
17
18
Attributes
19
----------
20
name : str
21
Name of the model
22
status : str
23
Current status of the model (e.g., 'Active', 'Initializing', 'Suspended')
24
hosting_platform : str
25
Hosting platform (e.g., 'Nova', 'Amazon', 'Azure')
26
"""
27
28
def __init__(
29
self,
30
name: str,
31
status: str,
32
hosting_platform: str,
33
):
34
self.name = name
35
self.status = status
36
self.hosting_platform = hosting_platform
37
38
@classmethod
39
def from_start_response(cls, response: Dict[str, Any]) -> 'ModelOperationResult':
40
"""
41
Create a ModelOperationResult from a start operation response.
42
43
Parameters
44
----------
45
response : dict
46
Response from the start endpoint
47
48
Returns
49
-------
50
ModelOperationResult
51
52
"""
53
return cls(
54
name=response.get('modelName', ''),
55
status='Initializing',
56
hosting_platform=response.get('hostingPlatform', ''),
57
)
58
59
@classmethod
60
def from_stop_response(cls, response: Dict[str, Any]) -> 'ModelOperationResult':
61
"""
62
Create a ModelOperationResult from a stop operation response.
63
64
Parameters
65
----------
66
response : dict
67
Response from the stop endpoint
68
69
Returns
70
-------
71
ModelOperationResult
72
73
"""
74
return cls(
75
name=response.get('name', ''),
76
status=response.get('status', 'Suspended'),
77
hosting_platform=response.get('hostingPlatform', ''),
78
)
79
80
@classmethod
81
def from_drop_response(cls, response: Dict[str, Any]) -> 'ModelOperationResult':
82
"""
83
Create a ModelOperationResult from a drop operation response.
84
85
Parameters
86
----------
87
response : dict
88
Response from the drop endpoint
89
90
Returns
91
-------
92
ModelOperationResult
93
94
"""
95
return cls(
96
name=response.get('name', ''),
97
status=response.get('status', 'Deleted'),
98
hosting_platform=response.get('hostingPlatform', ''),
99
)
100
101
@classmethod
102
def from_show_response(cls, response: Dict[str, Any]) -> 'ModelOperationResult':
103
"""
104
Create a ModelOperationResult from a show operation response.
105
106
Parameters
107
----------
108
response : dict
109
Response from the show endpoint (single model info)
110
111
Returns
112
-------
113
ModelOperationResult
114
115
"""
116
return cls(
117
name=response.get('name', ''),
118
status=response.get('status', ''),
119
hosting_platform=response.get('hostingPlatform', ''),
120
)
121
122
def get_message(self) -> str:
123
"""
124
Get a human-readable message about the operation.
125
126
Returns
127
-------
128
str
129
Message describing the operation result
130
131
"""
132
return f'Model is {self.status}'
133
134
def __str__(self) -> str:
135
"""Return string representation."""
136
return vars_to_str(self)
137
138
def __repr__(self) -> str:
139
"""Return string representation."""
140
return str(self)
141
142
143
class InferenceAPIInfo(object):
144
"""
145
Inference API definition.
146
147
This object is not directly instantiated. It is used in results
148
of API calls on the :class:`InferenceAPIManager`. See :meth:`InferenceAPIManager.get`.
149
"""
150
151
service_id: str
152
model_name: str
153
name: str
154
connection_url: str
155
internal_connection_url: str
156
project_id: str
157
hosting_platform: str
158
_manager: Optional['InferenceAPIManager']
159
160
def __init__(
161
self,
162
service_id: str,
163
model_name: str,
164
name: str,
165
connection_url: str,
166
internal_connection_url: str,
167
project_id: str,
168
hosting_platform: str,
169
manager: Optional['InferenceAPIManager'] = None,
170
):
171
self.service_id = service_id
172
self.connection_url = connection_url
173
self.internal_connection_url = internal_connection_url
174
self.model_name = model_name
175
self.name = name
176
self.project_id = project_id
177
self.hosting_platform = hosting_platform
178
self._manager = manager
179
180
@classmethod
181
def from_dict(
182
cls,
183
obj: Dict[str, Any],
184
) -> 'InferenceAPIInfo':
185
"""
186
Construct a Inference API from a dictionary of values.
187
188
Parameters
189
----------
190
obj : dict
191
Dictionary of values
192
193
Returns
194
-------
195
:class:`Job`
196
197
"""
198
out = cls(
199
service_id=obj['serviceID'],
200
project_id=obj['projectID'],
201
model_name=obj['modelName'],
202
name=obj['name'],
203
connection_url=obj['connectionURL'],
204
internal_connection_url=obj['internalConnectionURL'],
205
hosting_platform=obj['hostingPlatform'],
206
)
207
return out
208
209
def __str__(self) -> str:
210
"""Return string representation."""
211
return vars_to_str(self)
212
213
def __repr__(self) -> str:
214
"""Return string representation."""
215
return str(self)
216
217
def start(self) -> ModelOperationResult:
218
"""
219
Start this inference API model.
220
221
Returns
222
-------
223
ModelOperationResult
224
Result object containing status information about the started model
225
226
"""
227
if self._manager is None:
228
raise ManagementError(msg='No manager associated with this inference API')
229
return self._manager.start(self.name)
230
231
def stop(self) -> ModelOperationResult:
232
"""
233
Stop this inference API model.
234
235
Returns
236
-------
237
ModelOperationResult
238
Result object containing status information about the stopped model
239
240
"""
241
if self._manager is None:
242
raise ManagementError(msg='No manager associated with this inference API')
243
return self._manager.stop(self.name)
244
245
def drop(self) -> ModelOperationResult:
246
"""
247
Drop this inference API model.
248
249
Returns
250
-------
251
ModelOperationResult
252
Result object containing status information about the dropped model
253
254
"""
255
if self._manager is None:
256
raise ManagementError(msg='No manager associated with this inference API')
257
return self._manager.drop(self.name)
258
259
260
class InferenceAPIManager(object):
261
"""
262
SingleStoreDB Inference APIs manager.
263
264
This class should be instantiated using :attr:`Organization.inference_apis`.
265
266
Parameters
267
----------
268
manager : InferenceAPIManager, optional
269
The InferenceAPIManager the InferenceAPIManager belongs to
270
271
See Also
272
--------
273
:attr:`InferenceAPI`
274
"""
275
276
def __init__(self, manager: Optional[Manager]):
277
self._manager = manager
278
self.project_id = os.environ.get('SINGLESTOREDB_PROJECT')
279
280
def get(self, model_name: str) -> InferenceAPIInfo:
281
if self._manager is None:
282
raise ManagementError(msg='Manager not initialized')
283
res = self._manager._get(f'inferenceapis/{self.project_id}/{model_name}').json()
284
inference_api = InferenceAPIInfo.from_dict(res)
285
inference_api._manager = self # Associate the manager
286
return inference_api
287
288
def start(self, model_name: str) -> ModelOperationResult:
289
"""
290
Start an inference API model.
291
292
Parameters
293
----------
294
model_name : str
295
Name of the model to start
296
297
Returns
298
-------
299
ModelOperationResult
300
Result object containing status information about the started model
301
302
"""
303
if self._manager is None:
304
raise ManagementError(msg='Manager not initialized')
305
res = self._manager._post(f'models/{model_name}/start')
306
return ModelOperationResult.from_start_response(res.json())
307
308
def stop(self, model_name: str) -> ModelOperationResult:
309
"""
310
Stop an inference API model.
311
312
Parameters
313
----------
314
model_name : str
315
Name of the model to stop
316
317
Returns
318
-------
319
ModelOperationResult
320
Result object containing status information about the stopped model
321
322
"""
323
if self._manager is None:
324
raise ManagementError(msg='Manager not initialized')
325
res = self._manager._post(f'models/{model_name}/stop')
326
return ModelOperationResult.from_stop_response(res.json())
327
328
def show(self) -> List[ModelOperationResult]:
329
"""
330
Show all inference APIs in the project.
331
332
Returns
333
-------
334
List[ModelOperationResult]
335
List of ModelOperationResult objects with status information
336
337
"""
338
if self._manager is None:
339
raise ManagementError(msg='Manager not initialized')
340
res = self._manager._get('models').json()
341
return [ModelOperationResult.from_show_response(api) for api in res]
342
343
def drop(self, model_name: str) -> ModelOperationResult:
344
"""
345
Drop an inference API model.
346
347
Parameters
348
----------
349
model_name : str
350
Name of the model to drop
351
352
Returns
353
-------
354
ModelOperationResult
355
Result object containing status information about the dropped model
356
357
"""
358
if self._manager is None:
359
raise ManagementError(msg='Manager not initialized')
360
res = self._manager._delete(f'models/{model_name}')
361
return ModelOperationResult.from_drop_response(res.json())
362
363