select-ai 1.0.0b1__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.

@@ -0,0 +1,552 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Copyright (c) 2025, Oracle and/or its affiliates.
3
+ #
4
+ # Licensed under the Universal Permissive License v 1.0 as shown at
5
+ # http://oss.oracle.com/licenses/upl.
6
+ # -----------------------------------------------------------------------------
7
+
8
+ import json
9
+ from abc import ABC
10
+ from dataclasses import dataclass
11
+ from typing import AsyncGenerator, Iterator, Optional, Union
12
+
13
+ import oracledb
14
+
15
+ from select_ai import BaseProfile
16
+ from select_ai._abc import SelectAIDataClass
17
+ from select_ai._enums import StrEnum
18
+ from select_ai.async_profile import AsyncProfile
19
+ from select_ai.db import async_cursor, cursor
20
+ from select_ai.errors import VectorIndexNotFoundError
21
+ from select_ai.profile import Profile
22
+ from select_ai.sql import (
23
+ GET_USER_VECTOR_INDEX_ATTRIBUTES,
24
+ LIST_USER_VECTOR_INDEXES,
25
+ )
26
+
27
+
28
+ class VectorDBProvider(StrEnum):
29
+ ORACLE = "oracle"
30
+
31
+
32
+ class VectorDistanceMetric(StrEnum):
33
+ EUCLIDEAN = "EUCLIDEAN"
34
+ L2_SQUARED = "L2_SQUARED"
35
+ COSINE = "COSINE"
36
+ DOT = "DOT"
37
+ MANHATTAN = "MANHATTAN"
38
+ HAMMING = "HAMMING"
39
+
40
+
41
+ @dataclass
42
+ class VectorIndexAttributes(SelectAIDataClass):
43
+ """
44
+ Attributes of a vector index help to manage and configure the behavior of
45
+ the vector index.
46
+
47
+ :param int chunk_size: Text size of chunking the input data.
48
+ :param int chunk_overlap: Specifies the amount of overlapping
49
+ characters between adjacent chunks of text.
50
+ :param str location: Location of the object store.
51
+ :param int match_limit: Specifies the maximum number of results to return
52
+ in a vector search query
53
+ :param str object_storage_credential_name: Name of the credentials for
54
+ accessing object storage.
55
+ :param str profile_name: Name of the AI profile which is used for
56
+ embedding source data and user prompts.
57
+ :param int refresh_rate: Interval of updating data in the vector store.
58
+ The unit is minutes.
59
+ :param float similarity_threshold: Defines the minimum level of similarity
60
+ required for two items to be considered a match
61
+ :param VectorDistanceMetric vector_distance_metric: Specifies the type of
62
+ distance calculation used to compare vectors in a database
63
+ :param VectorDBProvider vector_db_provider: Name of the Vector database
64
+ provider. Default value is "oracle"
65
+ :param str vector_db_endpoint: Endpoint to access the Vector database
66
+ :param str vector_db_credential_name: Name of the credentials for accessing
67
+ Vector database
68
+ :param int vector_dimension: Specifies the number of elements in each
69
+ vector within the vector store
70
+ :param str vector_table_name: Specifies the name of the table or collection
71
+ to store vector embeddings and chunked data
72
+ """
73
+
74
+ chunk_size: Optional[int] = 1024
75
+ chunk_overlap: Optional[int] = 128
76
+ location: Optional[str] = None
77
+ match_limit: Optional[int] = 5
78
+ object_storage_credential_name: Optional[str] = None
79
+ profile_name: Optional[str] = None
80
+ refresh_rate: Optional[int] = 1440
81
+ similarity_threshold: Optional[float] = 0
82
+ vector_distance_metric: Optional[VectorDistanceMetric] = (
83
+ VectorDistanceMetric.COSINE
84
+ )
85
+ vector_db_endpoint: Optional[str] = None
86
+ vector_db_credential_name: Optional[str] = None
87
+ vector_db_provider: Optional[VectorDBProvider] = None
88
+ vector_dimension: Optional[int] = None
89
+ vector_table_name: Optional[str] = None
90
+ pipeline_name: Optional[str] = None
91
+
92
+ def json(self, exclude_null=True):
93
+ attributes = self.dict(exclude_null=exclude_null)
94
+ attributes.pop("pipeline_name", None)
95
+ return json.dumps(attributes)
96
+
97
+ @classmethod
98
+ def create(cls, *, vector_db_provider: Optional[str] = None, **kwargs):
99
+ for subclass in cls.__subclasses__():
100
+ if subclass.vector_db_provider == vector_db_provider:
101
+ return subclass(**kwargs)
102
+ return cls(**kwargs)
103
+
104
+
105
+ @dataclass
106
+ class OracleVectorIndexAttributes(VectorIndexAttributes):
107
+ """Oracle specific vector index attributes"""
108
+
109
+ vector_db_provider: Optional[VectorDBProvider] = VectorDBProvider.ORACLE
110
+
111
+
112
+ class _BaseVectorIndex(ABC):
113
+
114
+ def __init__(
115
+ self,
116
+ profile: BaseProfile = None,
117
+ index_name: Optional[str] = None,
118
+ description: Optional[str] = None,
119
+ attributes: Optional[VectorIndexAttributes] = None,
120
+ ):
121
+ """Initialize a Vector Index"""
122
+ self.profile = profile
123
+ self.index_name = index_name
124
+ self.attributes = attributes
125
+ self.description = description
126
+
127
+ def __repr__(self):
128
+ return (
129
+ f"{self.__class__.__name__}(profile={self.profile}, "
130
+ f"index_name={self.index_name}, "
131
+ f"attributes={self.attributes}, description={self.description})"
132
+ )
133
+
134
+
135
+ class VectorIndex(_BaseVectorIndex):
136
+ """
137
+ VectorIndex objects let you manage vector indexes
138
+
139
+ :param str index_name: The name of the vector index
140
+ :param str description: The description of the vector index
141
+ :param select_ai.VectorIndexAttributes attributes: The attributes of the vector index
142
+ """
143
+
144
+ @staticmethod
145
+ def _get_attributes(index_name: str) -> VectorIndexAttributes:
146
+ """Get attributes of a vector index
147
+
148
+ :return: select_ai.VectorIndexAttributes
149
+ :raises: VectorIndexNotFoundError
150
+ """
151
+ with cursor() as cr:
152
+ cr.execute(GET_USER_VECTOR_INDEX_ATTRIBUTES, index_name=index_name)
153
+ attributes = cr.fetchall()
154
+ if attributes:
155
+ post_processed_attributes = {}
156
+ for k, v in attributes:
157
+ if isinstance(v, oracledb.LOB):
158
+ post_processed_attributes[k] = v.read()
159
+ else:
160
+ post_processed_attributes[k] = v
161
+ return VectorIndexAttributes.create(
162
+ **post_processed_attributes
163
+ )
164
+ else:
165
+ raise VectorIndexNotFoundError(index_name=index_name)
166
+
167
+ def create(self, replace: Optional[bool] = False):
168
+ """Create a vector index in the database and populates the index
169
+ with data from an object store bucket using an async scheduler job
170
+
171
+ :param bool replace: Replace vector index if it exists
172
+ :return: None
173
+ """
174
+
175
+ if self.attributes.profile_name is None:
176
+ self.attributes.profile_name = self.profile.profile_name
177
+
178
+ parameters = {
179
+ "index_name": self.index_name,
180
+ "attributes": self.attributes.json(),
181
+ }
182
+
183
+ if self.description:
184
+ parameters["description"] = self.description
185
+
186
+ with cursor() as cr:
187
+ try:
188
+ cr.callproc(
189
+ "DBMS_CLOUD_AI.CREATE_VECTOR_INDEX",
190
+ keyword_parameters=parameters,
191
+ )
192
+ except oracledb.DatabaseError as e:
193
+ (error,) = e.args
194
+ # If already exists and replace is True then drop and recreate
195
+ if error.code == 20048 and replace:
196
+ self.delete(force=True)
197
+ cr.callproc(
198
+ "DBMS_CLOUD_AI.CREATE_VECTOR_INDEX",
199
+ keyword_parameters=parameters,
200
+ )
201
+ else:
202
+ raise
203
+ self.profile.set_attribute("vector_index_name", self.index_name)
204
+
205
+ def delete(
206
+ self,
207
+ include_data: Optional[bool] = True,
208
+ force: Optional[bool] = False,
209
+ ):
210
+ """This procedure removes a vector store index
211
+
212
+ :param bool include_data: Indicates whether to delete
213
+ both the customer's vector store and vector index
214
+ along with the vector index object
215
+ :param bool force: Indicates whether to ignore errors
216
+ that occur if the vector index does not exist
217
+ :return: None
218
+ :raises: oracledb.DatabaseError
219
+ """
220
+ with cursor() as cr:
221
+ cr.callproc(
222
+ "DBMS_CLOUD_AI.DROP_VECTOR_INDEX",
223
+ keyword_parameters={
224
+ "index_name": self.index_name,
225
+ "include_data": include_data,
226
+ "force": force,
227
+ },
228
+ )
229
+
230
+ def enable(self):
231
+ """This procedure enables or activates a previously disabled vector
232
+ index object. Generally, when you create a vector index, by default
233
+ it is enabled such that the AI profile can use it to perform indexing
234
+ and searching.
235
+
236
+ :return: None
237
+ :raises: oracledb.DatabaseError
238
+
239
+ """
240
+ with cursor() as cr:
241
+ cr.callproc(
242
+ "DBMS_CLOUD_AI.ENABLE_VECTOR_INDEX",
243
+ keyword_parameters={"index_name": self.index_name},
244
+ )
245
+
246
+ def disable(self):
247
+ """This procedure disables a vector index object in the current
248
+ database. When disabled, an AI profile cannot use the vector index,
249
+ and the system does not load data into the vector store as new data
250
+ is added to the object store and does not perform indexing, searching
251
+ or querying based on the index.
252
+
253
+ :return: None
254
+ :raises: oracledb.DatabaseError
255
+ """
256
+ with cursor() as cr:
257
+ cr.callproc(
258
+ "DBMS_CLOUD_AI.DISABLE_VECTOR_INDEX",
259
+ keyword_parameters={"index_name": self.index_name},
260
+ )
261
+
262
+ def set_attributes(
263
+ self,
264
+ attribute_name: str,
265
+ attribute_value: Union[str, int, float],
266
+ attributes: VectorIndexAttributes = None,
267
+ ):
268
+ """
269
+ This procedure updates an existing vector store index with a specified
270
+ value of the vector index attribute. You can specify a single attribute
271
+ or multiple attributes by passing an object of type
272
+ :class `VectorIndexAttributes`
273
+
274
+ :param str attribute_name: Custom attribute name
275
+ :param Union[str, int, float] attribute_value: Attribute Value
276
+ :param VectorIndexAttributes attributes: Specify multiple attributes
277
+ to update in a single API invocation
278
+ :return: None
279
+ :raises: oracledb.DatabaseError
280
+ """
281
+ if attribute_name and attribute_value and attributes:
282
+ raise ValueError(
283
+ "Either specify a single attribute using "
284
+ "attribute_name and attribute_value or "
285
+ "pass an object of type VectorIndexAttributes"
286
+ )
287
+
288
+ parameters = {"index_name": self.index_name}
289
+ if attributes:
290
+ parameters["attributes"] = attributes.json()
291
+ self.attributes = attributes
292
+ else:
293
+ setattr(self.attributes, attribute_name, attribute_value)
294
+ parameters["attributes_name"] = attribute_name
295
+ parameters["attributes_value"] = attribute_value
296
+
297
+ with cursor() as cr:
298
+ cr.callproc(
299
+ "DBMS_CLOUD_AI.UPDATE_VECTOR_INDEX",
300
+ keyword_parameters=parameters,
301
+ )
302
+
303
+ def get_attributes(self) -> VectorIndexAttributes:
304
+ """Get attributes of this vector index
305
+
306
+ :return: select_ai.VectorIndexAttributes
307
+ :raises: VectorIndexNotFoundError
308
+ """
309
+ return self._get_attributes(self.index_name)
310
+
311
+ @classmethod
312
+ def list(cls, index_name_pattern: str = ".*") -> Iterator["VectorIndex"]:
313
+ """List Vector Indexes
314
+
315
+ :param str index_name_pattern: Regular expressions can be used
316
+ to specify a pattern. Function REGEXP_LIKE is used to perform the
317
+ match. Default value is ".*" i.e. match all vector indexes.
318
+
319
+ :return: Iterator[VectorIndex]
320
+ """
321
+ with cursor() as cr:
322
+ cr.execute(
323
+ LIST_USER_VECTOR_INDEXES,
324
+ index_name_pattern=index_name_pattern,
325
+ )
326
+ for row in cr.fetchall():
327
+ index_name = row[0]
328
+ if row[1]:
329
+ description = row[1].read() # Oracle.LOB
330
+ else:
331
+ description = None
332
+ attributes = cls._get_attributes(index_name=index_name)
333
+ yield cls(
334
+ index_name=index_name,
335
+ description=description,
336
+ attributes=attributes,
337
+ profile=Profile(profile_name=attributes.profile_name),
338
+ )
339
+
340
+
341
+ class AsyncVectorIndex(_BaseVectorIndex):
342
+ """
343
+ AsyncVectorIndex objects let you manage vector indexes
344
+ using async APIs. Use this for non-blocking concurrent
345
+ requests
346
+
347
+ :param str index_name: The name of the vector index
348
+ :param str description: The description of the vector index
349
+ :param VectorIndexAttributes attributes: The attributes of the vector index
350
+ """
351
+
352
+ @staticmethod
353
+ async def _get_attributes(index_name: str) -> VectorIndexAttributes:
354
+ """Get attributes of a vector index
355
+
356
+ :return: select_ai.VectorIndexAttributes
357
+ :raises: VectorIndexNotFoundError
358
+ """
359
+ async with async_cursor() as cr:
360
+ await cr.execute(
361
+ GET_USER_VECTOR_INDEX_ATTRIBUTES, index_name=index_name
362
+ )
363
+ attributes = await cr.fetchall()
364
+ if attributes:
365
+ post_processed_attributes = {}
366
+ for k, v in attributes:
367
+ if isinstance(v, oracledb.AsyncLOB):
368
+ post_processed_attributes[k] = await v.read()
369
+ else:
370
+ post_processed_attributes[k] = v
371
+ return VectorIndexAttributes.create(
372
+ **post_processed_attributes
373
+ )
374
+ else:
375
+ raise VectorIndexNotFoundError(index_name=index_name)
376
+
377
+ async def create(self, replace: Optional[bool] = False) -> None:
378
+ """Create a vector index in the database and populates it with data
379
+ from an object store bucket using an async scheduler job
380
+
381
+ :param bool replace: True to replace existing vector index
382
+
383
+ """
384
+
385
+ if self.attributes.profile_name is None:
386
+ self.attributes.profile_name = self.profile.profile_name
387
+ parameters = {
388
+ "index_name": self.index_name,
389
+ "attributes": self.attributes.json(),
390
+ }
391
+ if self.description:
392
+ parameters["description"] = self.description
393
+ async with async_cursor() as cr:
394
+ try:
395
+ await cr.callproc(
396
+ "DBMS_CLOUD_AI.CREATE_VECTOR_INDEX",
397
+ keyword_parameters=parameters,
398
+ )
399
+ except oracledb.DatabaseError as e:
400
+ (error,) = e.args
401
+ # If already exists and replace is True then drop and recreate
402
+ if error.code == 20048 and replace:
403
+ await self.delete(force=True)
404
+ await cr.callproc(
405
+ "DBMS_CLOUD_AI.CREATE_VECTOR_INDEX",
406
+ keyword_parameters=parameters,
407
+ )
408
+ else:
409
+ raise
410
+
411
+ await self.profile.set_attribute("vector_index_name", self.index_name)
412
+
413
+ async def delete(
414
+ self,
415
+ include_data: Optional[bool] = True,
416
+ force: Optional[bool] = False,
417
+ ) -> None:
418
+ """This procedure removes a vector store index.
419
+
420
+ :param bool include_data: Indicates whether to delete
421
+ both the customer's vector store and vector index
422
+ along with the vector index object.
423
+ :param bool force: Indicates whether to ignore errors
424
+ that occur if the vector index does not exist.
425
+ :return: None
426
+ :raises: oracledb.DatabaseError
427
+
428
+ """
429
+ async with async_cursor() as cr:
430
+ await cr.callproc(
431
+ "DBMS_CLOUD_AI.DROP_VECTOR_INDEX",
432
+ keyword_parameters={
433
+ "index_name": self.index_name,
434
+ "include_data": include_data,
435
+ "force": force,
436
+ },
437
+ )
438
+
439
+ async def enable(self) -> None:
440
+ """This procedure enables or activates a previously disabled vector
441
+ index object. Generally, when you create a vector index, by default
442
+ it is enabled such that the AI profile can use it to perform indexing
443
+ and searching.
444
+
445
+ :return: None
446
+ :raises: oracledb.DatabaseError
447
+
448
+ """
449
+ async with async_cursor() as cr:
450
+ await cr.callproc(
451
+ "DBMS_CLOUD_AI.ENABLE_VECTOR_INDEX",
452
+ keyword_parameters={"index_name": self.index_name},
453
+ )
454
+
455
+ async def disable(self) -> None:
456
+ """This procedure disables a vector index object in the current
457
+ database. When disabled, an AI profile cannot use the vector index,
458
+ and the system does not load data into the vector store as new data
459
+ is added to the object store and does not perform indexing, searching
460
+ or querying based on the index.
461
+
462
+ :return: None
463
+ :raises: oracledb.DatabaseError
464
+ """
465
+ async with async_cursor() as cr:
466
+ await cr.callproc(
467
+ "DBMS_CLOUD_AI.DISABLE_VECTOR_INDEX",
468
+ keyword_parameters={"index_name": self.index_name},
469
+ )
470
+
471
+ async def set_attributes(
472
+ self,
473
+ attribute_name: str,
474
+ attribute_value: Union[str, int],
475
+ attributes: VectorIndexAttributes = None,
476
+ ) -> None:
477
+ """
478
+ This procedure updates an existing vector store index with a specified
479
+ value of the vector index attribute. You can specify a single attribute
480
+ or multiple attributes by passing an object of type
481
+ :class `VectorIndexAttributes`
482
+
483
+ :param str attribute_name: Custom attribute name
484
+ :param Union[str, int, float] attribute_value: Attribute Value
485
+ :param VectorIndexAttributes attributes: Specify multiple attributes
486
+ to update in a single API invocation
487
+ :return: None
488
+ :raises: oracledb.DatabaseError
489
+ """
490
+ if attribute_name and attribute_value and attributes:
491
+ raise ValueError(
492
+ "Either specify a single attribute using "
493
+ "attribute_name and attribute_value or "
494
+ "pass an object of type VectorIndexAttributes"
495
+ )
496
+ parameters = {"index_name": self.index_name}
497
+ if attributes:
498
+ self.attributes = attributes
499
+ parameters["attributes"] = attributes.json()
500
+ else:
501
+ setattr(self.attributes, attribute_name, attribute_value)
502
+ parameters["attributes_name"] = attribute_name
503
+ parameters["attributes_value"] = attribute_value
504
+
505
+ async with async_cursor() as cr:
506
+ await cr.callproc(
507
+ "DBMS_CLOUD_AI.UPDATE_VECTOR_INDEX",
508
+ keyword_parameters=parameters,
509
+ )
510
+
511
+ async def get_attributes(self) -> VectorIndexAttributes:
512
+ """Get attributes of a vector index
513
+
514
+ :return: select_ai.VectorIndexAttributes
515
+ :raises: VectorIndexNotFoundError
516
+ """
517
+ return await self._get_attributes(index_name=self.index_name)
518
+
519
+ @classmethod
520
+ async def list(
521
+ cls, index_name_pattern: str = ".*"
522
+ ) -> AsyncGenerator[VectorIndex, None]:
523
+ """List Vector Indexes.
524
+
525
+ :param str index_name_pattern: Regular expressions can be used
526
+ to specify a pattern. Function REGEXP_LIKE is used to perform the
527
+ match. Default value is ".*" i.e. match all vector indexes.
528
+
529
+ :return: AsyncGenerator[VectorIndex]
530
+
531
+ """
532
+ async with async_cursor() as cr:
533
+ await cr.execute(
534
+ LIST_USER_VECTOR_INDEXES,
535
+ index_name_pattern=index_name_pattern,
536
+ )
537
+ rows = await cr.fetchall()
538
+ for row in rows:
539
+ index_name = row[0]
540
+ if row[1]:
541
+ description = await row[1].read() # AsyncLOB
542
+ else:
543
+ description = None
544
+ attributes = await cls._get_attributes(index_name=index_name)
545
+ yield VectorIndex(
546
+ index_name=index_name,
547
+ description=description,
548
+ attributes=attributes,
549
+ profile=await AsyncProfile(
550
+ profile_name=attributes.profile_name
551
+ ),
552
+ )
select_ai/version.py ADDED
@@ -0,0 +1,8 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Copyright (c) 2025, Oracle and/or its affiliates.
3
+ #
4
+ # Licensed under the Universal Permissive License v 1.0 as shown at
5
+ # http://oss.oracle.com/licenses/upl.
6
+ # -----------------------------------------------------------------------------
7
+
8
+ __version__ = "1.0.0b1"
@@ -0,0 +1,117 @@
1
+ Metadata-Version: 2.4
2
+ Name: select_ai
3
+ Version: 1.0.0b1
4
+ Summary: Select AI for Python
5
+ Author-email: Abhishek Singh <abhishek.o.singh@oracle.com>
6
+ Maintainer-email: Abhishek Singh <abhishek.o.singh@oracle.com>
7
+ License-Expression: UPL-1.0
8
+ Project-URL: Homepage, https://github.com/oracle/python-select-ai
9
+ Project-URL: Repository, https://github.com/oracle/python-select-ai
10
+ Project-URL: Issues, https://github.com/oracle/python-select-ai/issues
11
+ Keywords: oracle,select-ai,adbs,autonomous database serverless
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Natural Language :: English
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: Implementation :: CPython
23
+ Classifier: Topic :: Database
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE.txt
27
+ Requires-Dist: oracledb
28
+ Requires-Dist: pandas==2.2.3
29
+ Dynamic: license-file
30
+
31
+ # Select AI for Python
32
+
33
+
34
+ Select AI for Python enables you to ask questions of your database data using natural language (text-to-SQL), get generative AI responses using your trusted content (retrieval augmented generation), generate synthetic data using large language models, and other features – all from Python. With the general availability of Select AI Python, Python developers have access to the functionality of Select AI on Oracle Autonomous Database.
35
+
36
+ Select AI for Python enables you to leverage the broader Python ecosystem in combination with generative AI and database functionality - bridging the gap between the DBMS_CLOUD_AI PL/SQL package and Python's rich ecosystem. It provides intuitive objects and methods for AI model interaction.
37
+
38
+
39
+ ## Installation
40
+
41
+ Run
42
+ ```bash
43
+ python3 -m pip install select_ai
44
+ ```
45
+
46
+ ## Samples
47
+
48
+ Examples can be found in the [/samples][samples] directory
49
+
50
+ ### Basic Example
51
+
52
+ ```python
53
+ import select_ai
54
+
55
+ user = "<your_select_ai_user>"
56
+ password = "<your_select_ai_password>"
57
+ dsn = "<your_select_ai_db_connect_string>"
58
+
59
+ select_ai.connect(user=user, password=password, dsn=dsn)
60
+ profile = select_ai.Profile(profile_name="oci_ai_profile")
61
+ # run_sql returns a pandas dataframe
62
+ df = profile.run_sql(prompt="How many promotions?")
63
+ print(df.columns)
64
+ print(df)
65
+ ```
66
+
67
+ ### Async Example
68
+
69
+ ```python
70
+
71
+ import asyncio
72
+
73
+ import select_ai
74
+
75
+ user = "<your_select_ai_user>"
76
+ password = "<your_select_ai_password>"
77
+ dsn = "<your_select_ai_db_connect_string>"
78
+
79
+ # This example shows how to asynchronously run sql
80
+ async def main():
81
+ await select_ai.async_connect(user=user, password=password, dsn=dsn)
82
+ async_profile = await select_ai.AsyncProfile(
83
+ profile_name="async_oci_ai_profile",
84
+ )
85
+ # run_sql returns a pandas df
86
+ df = await async_profile.run_sql("How many promotions?")
87
+ print(df)
88
+
89
+ asyncio.run(main())
90
+
91
+ ```
92
+ ## Help
93
+
94
+ Questions can be asked in [GitHub Discussions][ghdiscussions].
95
+
96
+ Problem reports can be raised in [GitHub Issues][ghissues].
97
+
98
+ ## Contributing
99
+
100
+ This project welcomes contributions from the community. Before submitting a pull request, please [review our contribution guide][contributing]
101
+
102
+ ## Security
103
+
104
+ Please consult the [security guide][security] for our responsible security vulnerability disclosure process
105
+
106
+ ## License
107
+
108
+ Copyright (c) 2025 Oracle and/or its affiliates.
109
+
110
+ Released under the Universal Permissive License v1.0 as shown at
111
+ <https://oss.oracle.com/licenses/upl/>.
112
+
113
+ [contributing]: https://github.com/oracle/python-select-ai/blob/main/CONTRIBUTING.md
114
+ [ghdiscussions]: https://github.com/oracle/python-select-ai/discussions
115
+ [ghissues]: https://github.com/oracle/python-select-ai/issues
116
+ [samples]: https://github.com/oracle/python-select-ai/tree/main/samples
117
+ [security]: https://github.com/oracle/python-select-ai/blob/main/SECURITY.md
@@ -0,0 +1,21 @@
1
+ select_ai/__init__.py,sha256=5oVcMxHqKPnIqzsPntFrqrMrTQ86bDrJsG8ARXuxN7U,1460
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/async_profile.py,sha256=rPBhA-Ofb5-FkWKnhHkzpbm6uEMs0hOa1YR18C50os4,18723
6
+ select_ai/base_profile.py,sha256=hY9thC-7pHvMwh01W0t7OzOAyG8Fi8Lnd0KhZ7ouVNs,7005
7
+ select_ai/conversation.py,sha256=fbYH7ROLwpyf1VzNtcrESG1S0_ZfLJ-uObbvbUATJUY,9622
8
+ select_ai/credential.py,sha256=cDIsiPgjbvckbOfb2LeoztPUsDO-6cJ_S8DzYT3pm4k,4220
9
+ select_ai/db.py,sha256=ipyXt5_wEXAQGl7PLVq82FBuePdA_e6b8ee_vhEAMks,4723
10
+ select_ai/errors.py,sha256=2T5eICWWjj7a907aRh7es5wTcvWm_wJiP8h0b3ipxVQ,2114
11
+ select_ai/profile.py,sha256=kYa2sO5wpPo8oxZQrhDL8EbT3Hl-XGfsP99A7lG3AWQ,16107
12
+ select_ai/provider.py,sha256=Sv0b-6SQJEoasPsnyHcWg1W8gS8nKldUW-83lL4MDm8,8285
13
+ select_ai/sql.py,sha256=9yCdB1H_sYpjMLs-6SB8xf5-QpTwCAx4cIgIsElvly4,2786
14
+ select_ai/synthetic_data.py,sha256=fClMI6ue2rNqzjY9TfeLA0_w1iPOahb08Y-1-gYzwzs,3305
15
+ select_ai/vector_index.py,sha256=C6a3jgZ6ffyel7fF5owHV_2G4T_E62pmGp1QXl28M4w,20475
16
+ select_ai/version.py,sha256=4TdM4bj5LoH5uC0TC9GTbDfMiXL0jHIH24wNf2w-Omk,345
17
+ select_ai-1.0.0b1.dist-info/licenses/LICENSE.txt,sha256=_0VqOxSjO1hu6JexZDVzqUXSmzH1A53EOfyiJzXTBKc,1840
18
+ select_ai-1.0.0b1.dist-info/METADATA,sha256=aQkg5QjpIs489tn4zEKTyAjj14MIGQnAUB_vV1yw2sY,4059
19
+ select_ai-1.0.0b1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
+ select_ai-1.0.0b1.dist-info/top_level.txt,sha256=u_QUAHDibro58Lvi_MU6a9Wc6VfQT8HEQm0cciMTP-c,10
21
+ select_ai-1.0.0b1.dist-info/RECORD,,