Skip to content

Commit 512cd8f

Browse files
authored
Add Wrapper for ChatOpenAI and OpenAIEmbeddings (#62)
1 parent c4c865f commit 512cd8f

File tree

5 files changed

+163
-15
lines changed

5 files changed

+163
-15
lines changed

singlestoredb/ai/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
from .chat import SingleStoreChatOpenAI # noqa: F401
12
from .embeddings import SingleStoreEmbeddings # noqa: F401

singlestoredb/ai/chat.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import os
2+
from typing import Any
3+
4+
from singlestoredb.fusion.handlers.utils import get_workspace_manager
5+
6+
try:
7+
from langchain_openai import ChatOpenAI
8+
except ImportError:
9+
raise ImportError(
10+
'Could not import langchain_openai python package. '
11+
'Please install it with `pip install langchain_openai`.',
12+
)
13+
14+
15+
class SingleStoreChatOpenAI(ChatOpenAI):
16+
def __init__(self, model_name: str, **kwargs: Any):
17+
inference_api_manger = (
18+
get_workspace_manager().organizations.current.inference_apis
19+
)
20+
info = inference_api_manger.get(model_name=model_name)
21+
super().__init__(
22+
base_url=info.connection_url,
23+
api_key=os.environ.get('SINGLESTOREDB_USER_TOKEN'),
24+
model=model_name,
25+
**kwargs,
26+
)

singlestoredb/ai/embeddings.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
1-
import os as _os
1+
import os
22
from typing import Any
33

4+
from singlestoredb.fusion.handlers.utils import get_workspace_manager
5+
46
try:
5-
from langchain_community.embeddings.ollama import OllamaEmbeddings
7+
from langchain_openai import OpenAIEmbeddings
68
except ImportError:
79
raise ImportError(
8-
'Could not import langchain_community python package. '
9-
'Please install it with `pip install langchain_community`.',
10+
'Could not import langchain_openai python package. '
11+
'Please install it with `pip install langchain_openai`.',
1012
)
1113

1214

13-
class SingleStoreEmbeddings(OllamaEmbeddings):
14-
15-
def __init__(self, **kwargs: Any):
16-
url = _os.getenv('SINGLESTORE_AI_EXPERIMENTAL_URL')
17-
if not url:
18-
raise ValueError(
19-
"Environment variable 'SINGLESTORE_AI_EXPERIMENTAL_URL' must be set",
20-
)
15+
class SingleStoreEmbeddings(OpenAIEmbeddings):
2116

22-
base_url = url.strip('/v1')
23-
kwargs = {'model': 'nomic-embed-text', **kwargs}
24-
super().__init__(base_url=base_url, **kwargs)
17+
def __init__(self, model_name: str, **kwargs: Any):
18+
inference_api_manger = (
19+
get_workspace_manager().organizations.current.inference_apis
20+
)
21+
info = inference_api_manger.get(model_name=model_name)
22+
super().__init__(
23+
base_url=info.connection_url,
24+
api_key=os.environ.get('SINGLESTOREDB_USER_TOKEN'),
25+
model=model_name,
26+
**kwargs,
27+
)
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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 Optional
7+
8+
from .utils import vars_to_str
9+
from singlestoredb.exceptions import ManagementError
10+
from singlestoredb.management.manager import Manager
11+
12+
13+
class InferenceAPIInfo(object):
14+
"""
15+
Inference API definition.
16+
17+
This object is not directly instantiated. It is used in results
18+
of API calls on the :class:`InferenceAPIManager`. See :meth:`InferenceAPIManager.get`.
19+
"""
20+
21+
service_id: str
22+
model_name: str
23+
name: str
24+
connection_url: str
25+
project_id: str
26+
27+
def __init__(
28+
self,
29+
service_id: str,
30+
model_name: str,
31+
name: str,
32+
connection_url: str,
33+
project_id: str,
34+
):
35+
self.service_id = service_id
36+
self.connection_url = connection_url
37+
self.model_name = model_name
38+
self.name = name
39+
self.project_id = project_id
40+
41+
@classmethod
42+
def from_dict(
43+
cls,
44+
obj: Dict[str, Any],
45+
) -> 'InferenceAPIInfo':
46+
"""
47+
Construct a Inference API from a dictionary of values.
48+
49+
Parameters
50+
----------
51+
obj : dict
52+
Dictionary of values
53+
54+
Returns
55+
-------
56+
:class:`Job`
57+
58+
"""
59+
out = cls(
60+
service_id=obj['serviceID'],
61+
project_id=obj['projectID'],
62+
model_name=obj['modelName'],
63+
name=obj['name'],
64+
connection_url=obj['connectionURL'],
65+
)
66+
return out
67+
68+
def __str__(self) -> str:
69+
"""Return string representation."""
70+
return vars_to_str(self)
71+
72+
def __repr__(self) -> str:
73+
"""Return string representation."""
74+
return str(self)
75+
76+
77+
class InferenceAPIManager(object):
78+
"""
79+
SingleStoreDB Inference APIs manager.
80+
81+
This class should be instantiated using :attr:`Organization.inference_apis`.
82+
83+
Parameters
84+
----------
85+
manager : InferenceAPIManager, optional
86+
The InferenceAPIManager the InferenceAPIManager belongs to
87+
88+
See Also
89+
--------
90+
:attr:`InferenceAPI`
91+
"""
92+
93+
def __init__(self, manager: Optional[Manager]):
94+
self._manager = manager
95+
self.project_id = os.environ.get('SINGLESTOREDB_PROJECT')
96+
97+
def get(self, model_name: str) -> InferenceAPIInfo:
98+
if self._manager is None:
99+
raise ManagementError(msg='Manager not initialized')
100+
res = self._manager._get(f'inferenceapis/{self.project_id}/{model_name}').json()
101+
return InferenceAPIInfo.from_dict(res)

singlestoredb/management/organization.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import Union
88

99
from ..exceptions import ManagementError
10+
from .inference_api import InferenceAPIManager
1011
from .job import JobsManager
1112
from .manager import Manager
1213
from .utils import vars_to_str
@@ -207,3 +208,19 @@ def jobs(self) -> JobsManager:
207208
:class:`JobsManager`
208209
"""
209210
return JobsManager(self._manager)
211+
212+
@property
213+
def inference_apis(self) -> InferenceAPIManager:
214+
"""
215+
Retrieve a SingleStoreDB inference api manager.
216+
217+
Parameters
218+
----------
219+
manager : WorkspaceManager, optional
220+
The WorkspaceManager the InferenceAPIManager belongs to
221+
222+
Returns
223+
-------
224+
:class:`InferenceAPIManager`
225+
"""
226+
return InferenceAPIManager(self._manager)

0 commit comments

Comments
 (0)