select-ai 1.0.0.dev4__py3-none-any.whl → 1.0.0.dev6__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.

Potentially problematic release.


This version of select-ai might be problematic. Click here for more details.

select_ai/__init__.py CHANGED
@@ -21,9 +21,11 @@ from .conversation import (
21
21
  from .db import (
22
22
  async_connect,
23
23
  async_cursor,
24
+ async_disconnect,
24
25
  async_is_connected,
25
26
  connect,
26
27
  cursor,
28
+ disconnect,
27
29
  is_connected,
28
30
  )
29
31
  from .profile import Profile
select_ai/_abc.py CHANGED
@@ -19,13 +19,14 @@ def _bool(value: Any) -> bool:
19
19
  return value
20
20
  if isinstance(value, int):
21
21
  return bool(value)
22
- if value.lower() in ('yes', 'true', 't', 'y', '1'):
22
+ if value.lower() in ("yes", "true", "t", "y", "1"):
23
23
  return True
24
- elif value.lower() in ('no', 'false', 'f', 'n', '0'):
24
+ elif value.lower() in ("no", "false", "f", "n", "0"):
25
25
  return False
26
26
  else:
27
27
  raise ValueError(f"Invalid boolean value: {value}")
28
28
 
29
+
29
30
  @dataclass
30
31
  class SelectAIDataClass(ABC):
31
32
  """SelectAIDataClass is an abstract container for all data
@@ -72,3 +73,5 @@ class SelectAIDataClass(ABC):
72
73
  List[typing.Mapping]
73
74
  ] and isinstance(value, (str, bytes, bytearray)):
74
75
  setattr(self, field.name, json.loads(value))
76
+ else:
77
+ setattr(self, field.name, value)
select_ai/admin.py CHANGED
@@ -5,7 +5,7 @@
5
5
  # http://oss.oracle.com/licenses/upl.
6
6
  # -----------------------------------------------------------------------------
7
7
 
8
- from typing import List, Mapping
8
+ from typing import List, Mapping, Union
9
9
 
10
10
  import oracledb
11
11
 
@@ -70,13 +70,17 @@ def create_credential(credential: Mapping, replace: bool = False):
70
70
  raise
71
71
 
72
72
 
73
- def enable_provider(users: List[str], provider_endpoint: str = None):
73
+ def enable_provider(
74
+ users: Union[str, List[str]], provider_endpoint: str = None
75
+ ):
74
76
  """
75
77
  Enables AI profile for the user. This method grants execute privilege
76
78
  on the packages DBMS_CLOUD, DBMS_CLOUD_AI and DBMS_CLOUD_PIPELINE. It
77
79
  also enables the user to invoke the AI(LLM) endpoint hosted at a
78
80
  certain domain
79
81
  """
82
+ if isinstance(users, str):
83
+ users = [users]
80
84
 
81
85
  with cursor() as cr:
82
86
  for user in users:
@@ -89,13 +93,17 @@ def enable_provider(users: List[str], provider_endpoint: str = None):
89
93
  )
90
94
 
91
95
 
92
- def disable_provider(users: List[str], provider_endpoint: str = None):
96
+ def disable_provider(
97
+ users: Union[str, List[str]], provider_endpoint: str = None
98
+ ):
93
99
  """
94
100
  Disables AI provider for the user. This method revokes execute privilege
95
101
  on the packages DBMS_CLOUD, DBMS_CLOUD_AI and DBMS_CLOUD_PIPELINE. It
96
102
  also disables the user to invoke the AI(LLM) endpoint hosted at a
97
103
  certain domain
98
104
  """
105
+ if isinstance(users, str):
106
+ users = [users]
99
107
 
100
108
  with cursor() as cr:
101
109
  for user in users:
@@ -24,9 +24,10 @@ from select_ai.action import Action
24
24
  from select_ai.base_profile import BaseProfile, ProfileAttributes
25
25
  from select_ai.conversation import AsyncConversation
26
26
  from select_ai.db import async_cursor, async_get_connection
27
- from select_ai.errors import ProfileNotFoundError
27
+ from select_ai.errors import ProfileExistsError, ProfileNotFoundError
28
28
  from select_ai.provider import Provider
29
29
  from select_ai.sql import (
30
+ GET_USER_AI_PROFILE,
30
31
  GET_USER_AI_PROFILE_ATTRIBUTES,
31
32
  LIST_USER_AI_PROFILES,
32
33
  )
@@ -61,6 +62,18 @@ class AsyncProfile(BaseProfile):
61
62
  profile_name=self.profile_name
62
63
  )
63
64
  profile_exists = True
65
+ if not self.replace and not self.merge:
66
+ if (
67
+ self.attributes is not None
68
+ or self.description is not None
69
+ ):
70
+ if self.raise_error_if_exists:
71
+ raise ProfileExistsError(self.profile_name)
72
+
73
+ if self.description is None:
74
+ self.description = await self._get_profile_description(
75
+ profile_name=self.profile_name
76
+ )
64
77
  except ProfileNotFoundError:
65
78
  if self.attributes is None:
66
79
  raise
@@ -80,6 +93,27 @@ class AsyncProfile(BaseProfile):
80
93
  )
81
94
  return self
82
95
 
96
+ @staticmethod
97
+ async def _get_profile_description(profile_name) -> str:
98
+ """Get description of profile from USER_CLOUD_AI_PROFILES
99
+
100
+ :param str profile_name: Name of profile
101
+ :return: Description of profile
102
+ :rtype: str
103
+ :raises: ProfileNotFoundError
104
+
105
+ """
106
+ async with async_cursor() as cr:
107
+ await cr.execute(
108
+ GET_USER_AI_PROFILE,
109
+ profile_name=profile_name.upper(),
110
+ )
111
+ profile = await cr.fetchone()
112
+ if profile:
113
+ return await profile[1].read()
114
+ else:
115
+ raise ProfileNotFoundError(profile_name)
116
+
83
117
  @staticmethod
84
118
  async def _get_attributes(profile_name) -> ProfileAttributes:
85
119
  """Asynchronously gets AI profile attributes from the Database
@@ -264,6 +298,7 @@ class AsyncProfile(BaseProfile):
264
298
  profile_name=profile_name,
265
299
  description=description,
266
300
  attributes=attributes,
301
+ raise_error_if_exists=False,
267
302
  )
268
303
 
269
304
  async def generate(
select_ai/base_profile.py CHANGED
@@ -72,6 +72,13 @@ class ProfileAttributes(SelectAIDataClass):
72
72
  temperature: Optional[float] = None
73
73
  vector_index_name: Optional[str] = None
74
74
 
75
+ def __post_init__(self):
76
+ if not isinstance(self.provider, Provider):
77
+ raise ValueError(
78
+ f"The arg `provider` must be an object of "
79
+ f"type select_ai.Provider"
80
+ )
81
+
75
82
  def json(self, exclude_null=True):
76
83
  attributes = {}
77
84
  for k, v in self.dict(exclude_null=exclude_null).items():
@@ -136,12 +143,16 @@ class BaseProfile(ABC):
136
143
  :param str description: Description of the profile
137
144
 
138
145
  :param bool merge: Fetches the profile
139
- from database, merges the attributes and saves it back
146
+ from database, merges the non-null attributes and saves it back
140
147
  in the database. Default value is False
141
148
 
142
149
  :param bool replace: Replaces the profile and attributes
143
150
  in the database. Default value is False
144
151
 
152
+ :param bool raise_error_if_exists: Raise ProfileExistsError
153
+ if profile exists in the database and replace = False and
154
+ merge = False. Default value is True
155
+
145
156
  """
146
157
 
147
158
  def __init__(
@@ -151,6 +162,7 @@ class BaseProfile(ABC):
151
162
  description: Optional[str] = None,
152
163
  merge: Optional[bool] = False,
153
164
  replace: Optional[bool] = False,
165
+ raise_error_if_exists: Optional[bool] = True,
154
166
  ):
155
167
  """Initialize a base profile"""
156
168
  self.profile_name = profile_name
@@ -158,6 +170,7 @@ class BaseProfile(ABC):
158
170
  self.description = description
159
171
  self.merge = merge
160
172
  self.replace = replace
173
+ self.raise_error_if_exists = raise_error_if_exists
161
174
 
162
175
  def __repr__(self):
163
176
  return (
select_ai/conversation.py CHANGED
@@ -5,6 +5,8 @@
5
5
  # http://oss.oracle.com/licenses/upl.
6
6
  # -----------------------------------------------------------------------------
7
7
 
8
+ import datetime
9
+ import json
8
10
  from dataclasses import dataclass
9
11
  from typing import AsyncGenerator, Iterator, Optional
10
12
 
@@ -27,17 +29,28 @@ class ConversationAttributes(SelectAIDataClass):
27
29
 
28
30
  :param str title: Conversation Title
29
31
  :param str description: Description of the conversation topic
30
- :param int retention_days: The number of days the conversation will be
31
- stored in the database from its creation date. If value is 0, we will
32
- not remove the conversation unless it is manually deleted by
33
- drop_conversation
32
+ :param datetime.timedelta retention_days: The number of days the conversation
33
+ will be stored in the database from its creation date. If value is 0, the
34
+ conversation will not be removed unless it is manually deleted by
35
+ delete
36
+ :param int conversation_length: Number of prompts to store for this
37
+ conversation
34
38
 
35
39
  """
36
40
 
37
41
  title: Optional[str] = "New Conversation"
38
42
  description: Optional[str] = None
39
- retention_days: Optional[int] = 7
40
- # conversation_length: Optional[int] = 10
43
+ retention_days: Optional[datetime.timedelta] = datetime.timedelta(days=7)
44
+ conversation_length: Optional[int] = 10
45
+
46
+ def json(self, exclude_null=True):
47
+ attributes = {}
48
+ for k, v in self.dict(exclude_null=exclude_null).items():
49
+ if isinstance(v, datetime.timedelta):
50
+ attributes[k] = v.days
51
+ else:
52
+ attributes[k] = v
53
+ return json.dumps(attributes)
41
54
 
42
55
 
43
56
  class _BaseConversation:
select_ai/db.py CHANGED
@@ -12,6 +12,8 @@ from typing import Dict, Hashable
12
12
 
13
13
  import oracledb
14
14
 
15
+ from select_ai.errors import DatabaseNotConnectedError
16
+
15
17
  __conn__: Dict[Hashable, oracledb.Connection] = {}
16
18
  __async_conn__: Dict[Hashable, oracledb.AsyncConnection] = {}
17
19
 
@@ -24,6 +26,8 @@ __all__ = [
24
26
  "async_get_connection",
25
27
  "cursor",
26
28
  "async_cursor",
29
+ "disconnect",
30
+ "async_disconnect",
27
31
  ]
28
32
 
29
33
 
@@ -109,10 +113,7 @@ def _set_connection(
109
113
  def get_connection() -> oracledb.Connection:
110
114
  """Returns the connection object if connection is healthy"""
111
115
  if not is_connected():
112
- raise Exception(
113
- "Not connected to the Database. "
114
- "Use select_ai.db.connect() to establish connection"
115
- )
116
+ raise DatabaseNotConnectedError()
116
117
  global __conn__
117
118
  key = (os.getpid(), get_ident())
118
119
  return __conn__[key]
@@ -121,11 +122,7 @@ def get_connection() -> oracledb.Connection:
121
122
  async def async_get_connection() -> oracledb.AsyncConnection:
122
123
  """Returns the AsyncConnection object if connection is healthy"""
123
124
  if not await async_is_connected():
124
- raise Exception(
125
- "Not connected to the Database. "
126
- "Use select_ai.db.async_connect() to establish "
127
- "connection"
128
- )
125
+ raise DatabaseNotConnectedError()
129
126
  global __async_conn__
130
127
  key = (os.getpid(), get_ident())
131
128
  return __async_conn__[key]
@@ -169,3 +166,21 @@ async def async_cursor():
169
166
  yield cr
170
167
  finally:
171
168
  cr.close()
169
+
170
+
171
+ def disconnect():
172
+ try:
173
+ conn = get_connection()
174
+ except DatabaseNotConnectedError:
175
+ pass
176
+ else:
177
+ conn.close()
178
+
179
+
180
+ async def async_disconnect():
181
+ try:
182
+ conn = await async_get_connection()
183
+ except DatabaseNotConnectedError:
184
+ pass
185
+ else:
186
+ await conn.close()
select_ai/errors.py CHANGED
@@ -12,6 +12,17 @@ class SelectAIError(Exception):
12
12
  pass
13
13
 
14
14
 
15
+ class DatabaseNotConnectedError(SelectAIError):
16
+ """Raised when a database is not connected"""
17
+
18
+ def __str__(self):
19
+ return (
20
+ "Not connected to the Database. "
21
+ "Use select_ai.connect() or select_ai.async_connect() "
22
+ "to establish connection"
23
+ )
24
+
25
+
15
26
  class ConversationNotFoundError(SelectAIError):
16
27
  """Conversation not found in the database"""
17
28
 
@@ -32,6 +43,19 @@ class ProfileNotFoundError(SelectAIError):
32
43
  return f"Profile {self.profile_name} not found"
33
44
 
34
45
 
46
+ class ProfileExistsError(SelectAIError):
47
+ """Profile already exists in the database"""
48
+
49
+ def __init__(self, profile_name: str):
50
+ self.profile_name = profile_name
51
+
52
+ def __str__(self):
53
+ return (
54
+ f"Profile {self.profile_name} already exists. "
55
+ f"Use either replace=True or merge=True"
56
+ )
57
+
58
+
35
59
  class VectorIndexNotFoundError(SelectAIError):
36
60
  """VectorIndex not found in the database"""
37
61
 
select_ai/profile.py CHANGED
@@ -17,9 +17,10 @@ from select_ai import Conversation
17
17
  from select_ai.action import Action
18
18
  from select_ai.base_profile import BaseProfile, ProfileAttributes
19
19
  from select_ai.db import cursor
20
- from select_ai.errors import ProfileNotFoundError
20
+ from select_ai.errors import ProfileExistsError, ProfileNotFoundError
21
21
  from select_ai.provider import Provider
22
22
  from select_ai.sql import (
23
+ GET_USER_AI_PROFILE,
23
24
  GET_USER_AI_PROFILE_ATTRIBUTES,
24
25
  LIST_USER_AI_PROFILES,
25
26
  )
@@ -50,6 +51,18 @@ class Profile(BaseProfile):
50
51
  profile_name=self.profile_name
51
52
  )
52
53
  profile_exists = True
54
+ if not self.replace and not self.merge:
55
+ if (
56
+ self.attributes is not None
57
+ or self.description is not None
58
+ ):
59
+ if self.raise_error_if_exists:
60
+ raise ProfileExistsError(self.profile_name)
61
+
62
+ if self.description is None:
63
+ self.description = self._get_profile_description(
64
+ profile_name=self.profile_name
65
+ )
53
66
  except ProfileNotFoundError:
54
67
  if self.attributes is None:
55
68
  raise
@@ -66,6 +79,22 @@ class Profile(BaseProfile):
66
79
  if self.replace or not profile_exists:
67
80
  self.create(replace=self.replace)
68
81
 
82
+ @staticmethod
83
+ def _get_profile_description(profile_name) -> str:
84
+ """Get description of profile from USER_CLOUD_AI_PROFILES
85
+
86
+ :param str profile_name:
87
+ :return: str
88
+ :raises: ProfileNotFoundError
89
+ """
90
+ with cursor() as cr:
91
+ cr.execute(GET_USER_AI_PROFILE, profile_name=profile_name.upper())
92
+ profile = cr.fetchone()
93
+ if profile:
94
+ return profile[1].read()
95
+ else:
96
+ raise ProfileNotFoundError(profile_name)
97
+
69
98
  @staticmethod
70
99
  def _get_attributes(profile_name) -> ProfileAttributes:
71
100
  """Get AI profile attributes from the Database
@@ -237,6 +266,7 @@ class Profile(BaseProfile):
237
266
  profile_name=profile_name,
238
267
  description=description,
239
268
  attributes=attributes,
269
+ raise_error_if_exists=False,
240
270
  )
241
271
 
242
272
  def generate(
@@ -354,7 +384,7 @@ class Profile(BaseProfile):
354
384
 
355
385
  def generate_synthetic_data(
356
386
  self, synthetic_data_attributes: SyntheticDataAttributes
357
- ):
387
+ ) -> None:
358
388
  """Generate synthetic data for a single table, multiple tables or a
359
389
  full schema.
360
390
 
select_ai/provider.py CHANGED
@@ -176,7 +176,6 @@ class AWSProvider(Provider):
176
176
  self.provider_endpoint = f"bedrock-runtime.{self.region}.amazonaws.com"
177
177
 
178
178
 
179
-
180
179
  @dataclass
181
180
  class AnthropicProvider(Provider):
182
181
  """
select_ai/sql.py CHANGED
@@ -64,7 +64,7 @@ WHERE profile_name = :profile_name
64
64
  """
65
65
 
66
66
  GET_USER_AI_PROFILE = """
67
- SELECT count(*)
67
+ SELECT profile_name, description
68
68
  FROM USER_CLOUD_AI_PROFILES
69
69
  WHERE profile_name = :profile_name
70
70
  """
select_ai/vector_index.py CHANGED
@@ -109,7 +109,6 @@ class OracleVectorIndexAttributes(VectorIndexAttributes):
109
109
  vector_db_provider: Optional[VectorDBProvider] = VectorDBProvider.ORACLE
110
110
 
111
111
 
112
-
113
112
  class _BaseVectorIndex(ABC):
114
113
 
115
114
  def __init__(
@@ -165,7 +164,7 @@ class VectorIndex(_BaseVectorIndex):
165
164
  else:
166
165
  raise VectorIndexNotFoundError(index_name=index_name)
167
166
 
168
- def create(self, replace=False):
167
+ def create(self, replace: Optional[bool] = False):
169
168
  """Create a vector index in the database and populates the index
170
169
  with data from an object store bucket using an async scheduler job
171
170
 
@@ -204,7 +203,9 @@ class VectorIndex(_BaseVectorIndex):
204
203
  self.profile.set_attribute("vector_index_name", self.index_name)
205
204
 
206
205
  def delete(
207
- self, include_data: Optional[int] = True, force: Optional[int] = False
206
+ self,
207
+ include_data: Optional[bool] = True,
208
+ force: Optional[bool] = False,
208
209
  ):
209
210
  """This procedure removes a vector store index
210
211
 
@@ -370,7 +371,7 @@ class AsyncVectorIndex(_BaseVectorIndex):
370
371
  else:
371
372
  raise VectorIndexNotFoundError(index_name=index_name)
372
373
 
373
- async def create(self, replace: Optional[int] = False) -> None:
374
+ async def create(self, replace: Optional[bool] = False) -> None:
374
375
  """Create a vector index in the database and populates it with data
375
376
  from an object store bucket using an async scheduler job
376
377
 
@@ -407,7 +408,9 @@ class AsyncVectorIndex(_BaseVectorIndex):
407
408
  await self.profile.set_attribute("vector_index_name", self.index_name)
408
409
 
409
410
  async def delete(
410
- self, include_data: Optional[int] = True, force: Optional[int] = False
411
+ self,
412
+ include_data: Optional[bool] = True,
413
+ force: Optional[bool] = False,
411
414
  ) -> None:
412
415
  """This procedure removes a vector store index.
413
416
 
select_ai/version.py CHANGED
@@ -5,4 +5,4 @@
5
5
  # http://oss.oracle.com/licenses/upl.
6
6
  # -----------------------------------------------------------------------------
7
7
 
8
- __version__ = "1.0.0.dev4"
8
+ __version__ = "1.0.0.dev6"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: select_ai
3
- Version: 1.0.0.dev4
3
+ Version: 1.0.0.dev6
4
4
  Summary: Python API for Select AI
5
5
  Author-email: Abhishek Singh <abhishek.o.singh@oracle.com>
6
6
  Maintainer-email: Abhishek Singh <abhishek.o.singh@oracle.com>
@@ -0,0 +1,21 @@
1
+ select_ai/__init__.py,sha256=LVdOh_JnWEXaXs0NSflA1f0YIWCUEpTBZCvWNTvSS74,1319
2
+ select_ai/_abc.py,sha256=ccec6yu54w5QMix_EKc_BJ_0JatUDXKjfLW9KshOGak,2692
3
+ select_ai/_enums.py,sha256=U0UavuE4pbRY-0-Qb8z-F7KfxU0YUfOgUahaSjDi0dU,416
4
+ select_ai/action.py,sha256=s78uhi5HHCLbTN2S5tLDSswTLUl40FZ3nESLka8CfZk,592
5
+ select_ai/admin.py,sha256=MMkXpvVJZUoloty8HiQnndPVPpuZch22Pnk8llUhUCc,3528
6
+ select_ai/async_profile.py,sha256=1_ds6Rej4m17cd5aaRM5LoPOIL0EL4OVYBULiCLj57M,17593
7
+ select_ai/base_profile.py,sha256=Iyd5GdBNqEISiWCwYpGSKOGd394f-A5QgHPtuJ547CE,6791
8
+ select_ai/conversation.py,sha256=jeZy7qtbnFTO9xTE3gNZLyxVI0Pnj_rpc0QZb1r-A00,9240
9
+ select_ai/db.py,sha256=Q0MvoIBzE0fHP1d9oFjvnjfgKqdRk6ZCM6bERokcM3E,4669
10
+ select_ai/errors.py,sha256=2T5eICWWjj7a907aRh7es5wTcvWm_wJiP8h0b3ipxVQ,2114
11
+ select_ai/profile.py,sha256=lyMnS1ExRPYwS54OqlLpH3WwJxkj_epat7Z_nVDH3Os,14868
12
+ select_ai/provider.py,sha256=7KNdU2BmUMzjPj2WAwtn0vEYPBYY83MvRTT1q2Ng5tM,5103
13
+ select_ai/sql.py,sha256=9yCdB1H_sYpjMLs-6SB8xf5-QpTwCAx4cIgIsElvly4,2786
14
+ select_ai/synthetic_data.py,sha256=lnjEIcUzr7lr2dO24OgxRhol-tiVOiKK-kEvFVJoiig,3078
15
+ select_ai/vector_index.py,sha256=y6Vrky7T5qNJK_eDVBS3U7i5B-Hvq6FBUd_CjkN23bo,20212
16
+ select_ai/version.py,sha256=4HksrDhF_YLN3qkAVlYmmmBl9tDnJJ1XbM3x2xA-XfM,348
17
+ select_ai-1.0.0.dev6.dist-info/licenses/LICENSE.txt,sha256=_0VqOxSjO1hu6JexZDVzqUXSmzH1A53EOfyiJzXTBKc,1840
18
+ select_ai-1.0.0.dev6.dist-info/METADATA,sha256=P_89Il0dtluoQWFYZpexYhvfs18iymZT05A0hI3cKe4,1016
19
+ select_ai-1.0.0.dev6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
+ select_ai-1.0.0.dev6.dist-info/top_level.txt,sha256=u_QUAHDibro58Lvi_MU6a9Wc6VfQT8HEQm0cciMTP-c,10
21
+ select_ai-1.0.0.dev6.dist-info/RECORD,,
@@ -1,21 +0,0 @@
1
- select_ai/__init__.py,sha256=JPm7f3IjEos8cbYr_hpwQKN6_sxG_gNgZXFqDpqxvrI,1281
2
- select_ai/_abc.py,sha256=PQZYYz2SKchPujRe7V58rmby6IlZ9bMnNpfOQYQ_EZk,2616
3
- select_ai/_enums.py,sha256=U0UavuE4pbRY-0-Qb8z-F7KfxU0YUfOgUahaSjDi0dU,416
4
- select_ai/action.py,sha256=s78uhi5HHCLbTN2S5tLDSswTLUl40FZ3nESLka8CfZk,592
5
- select_ai/admin.py,sha256=87OQEVmbFs6ftV4phLGHC1NGIWvD6x2Wu4Qic2DisRI,3375
6
- select_ai/async_profile.py,sha256=STAV1yLxCKJbYjFtW4uViAUa8j20lzQxYoToml435BM,16293
7
- select_ai/base_profile.py,sha256=YzromcmBdAmO9DX86L8_wwNtHYn8nPrHvUirYoxb5fA,6269
8
- select_ai/conversation.py,sha256=IulU5BHbBksk1zo4ppaR85-EVd0o7VUptkdHrBjKYeg,8770
9
- select_ai/db.py,sha256=G7yvE9UtUFpS46yXEv0_56lTqeve5r7mVGW7b8QmbEc,4484
10
- select_ai/errors.py,sha256=dMWdbsdWCpBPO1OD1zkDGUymJ37iBQDjEo9kb-PwirU,1470
11
- select_ai/profile.py,sha256=NX5-wP-HXBZJzyX9rlNElo3MZDC3A62r9QnPJge4k34,13705
12
- select_ai/provider.py,sha256=ycMMGMVix-4Pc54WOJXO6e2NvYZJYrMv7o-3tUKMlEc,5104
13
- select_ai/sql.py,sha256=_KQeBrHy9IXMI3N7PO064wp72gBzJGPfPMMNRprpxWs,2769
14
- select_ai/synthetic_data.py,sha256=lnjEIcUzr7lr2dO24OgxRhol-tiVOiKK-kEvFVJoiig,3078
15
- select_ai/vector_index.py,sha256=WnLP2QaqQUqT8BEs_nEyv02o-JfmuYx4V0pfUlflEz0,20156
16
- select_ai/version.py,sha256=MtG826c9kTe8me0o5cgLxZWIfgQxkiAmJIa1EyANzEI,348
17
- select_ai-1.0.0.dev4.dist-info/licenses/LICENSE.txt,sha256=_0VqOxSjO1hu6JexZDVzqUXSmzH1A53EOfyiJzXTBKc,1840
18
- select_ai-1.0.0.dev4.dist-info/METADATA,sha256=JXkOaJouXVgJT5qqNaBtD7uFQgXNjkINPDAobiiYc3k,1016
19
- select_ai-1.0.0.dev4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
- select_ai-1.0.0.dev4.dist-info/top_level.txt,sha256=u_QUAHDibro58Lvi_MU6a9Wc6VfQT8HEQm0cciMTP-c,10
21
- select_ai-1.0.0.dev4.dist-info/RECORD,,