select-ai 1.0.0rc1__tar.gz → 1.1.0__tar.gz

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.

Files changed (74) hide show
  1. {select_ai-1.0.0rc1/src/select_ai.egg-info → select_ai-1.1.0}/PKG-INFO +6 -1
  2. {select_ai-1.0.0rc1 → select_ai-1.1.0}/README.md +5 -0
  3. select_ai-1.1.0/samples/async/vector_index_get_attributes.py +36 -0
  4. select_ai-1.1.0/samples/async/vector_index_update_attributes.py +44 -0
  5. select_ai-1.1.0/samples/vector_index_get_attributes.py +29 -0
  6. select_ai-1.1.0/samples/vector_index_update_attributes.py +36 -0
  7. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/async_profile.py +8 -4
  8. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/base_profile.py +9 -0
  9. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/profile.py +8 -4
  10. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/vector_index.py +156 -35
  11. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/version.py +1 -1
  12. {select_ai-1.0.0rc1 → select_ai-1.1.0/src/select_ai.egg-info}/PKG-INFO +6 -1
  13. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai.egg-info/SOURCES.txt +4 -0
  14. {select_ai-1.0.0rc1 → select_ai-1.1.0}/LICENSE.txt +0 -0
  15. {select_ai-1.0.0rc1 → select_ai-1.1.0}/MANIFEST.in +0 -0
  16. {select_ai-1.0.0rc1 → select_ai-1.1.0}/pyproject.toml +0 -0
  17. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/conversation_chat_session.py +0 -0
  18. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/conversations_list.py +0 -0
  19. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/create_ai_credential.py +0 -0
  20. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/delete_ai_credential.py +0 -0
  21. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/disable_ai_provider.py +0 -0
  22. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/enable_ai_provider.py +0 -0
  23. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profile_chat.py +0 -0
  24. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profile_create.py +0 -0
  25. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profile_explain_sql.py +0 -0
  26. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profile_gen_multi_table_synthetic_data.py +0 -0
  27. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profile_gen_single_table_synthetic_data.py +0 -0
  28. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profile_pipeline.py +0 -0
  29. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profile_run_sql.py +0 -0
  30. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profile_show_sql.py +0 -0
  31. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profile_sql_concurrent_tasks.py +0 -0
  32. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/profiles_list.py +0 -0
  33. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/vector_index_create.py +0 -0
  34. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/vector_index_delete.py +0 -0
  35. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/vector_index_list.py +0 -0
  36. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/async/vector_index_rag.py +0 -0
  37. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/conversation_chat_session.py +0 -0
  38. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/conversation_create.py +0 -0
  39. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/conversation_delete.py +0 -0
  40. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/conversations_list.py +0 -0
  41. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/create_ai_credential.py +0 -0
  42. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/delete_ai_credential.py +0 -0
  43. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/disable_ai_provider.py +0 -0
  44. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/enable_ai_provider.py +0 -0
  45. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profile_chat.py +0 -0
  46. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profile_create.py +0 -0
  47. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profile_delete.py +0 -0
  48. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profile_explain_sql.py +0 -0
  49. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profile_gen_multi_table_synthetic_data.py +0 -0
  50. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profile_gen_single_table_synthetic_data.py +0 -0
  51. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profile_narrate.py +0 -0
  52. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profile_run_sql.py +0 -0
  53. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profile_show_sql.py +0 -0
  54. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/profiles_list.py +0 -0
  55. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/vector_index_create.py +0 -0
  56. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/vector_index_delete.py +0 -0
  57. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/vector_index_list.py +0 -0
  58. {select_ai-1.0.0rc1 → select_ai-1.1.0}/samples/vector_index_rag.py +0 -0
  59. {select_ai-1.0.0rc1 → select_ai-1.1.0}/setup.cfg +0 -0
  60. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/__init__.py +0 -0
  61. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/_abc.py +0 -0
  62. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/_enums.py +0 -0
  63. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/_validations.py +0 -0
  64. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/action.py +0 -0
  65. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/conversation.py +0 -0
  66. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/credential.py +0 -0
  67. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/db.py +0 -0
  68. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/errors.py +0 -0
  69. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/provider.py +0 -0
  70. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/sql.py +0 -0
  71. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai/synthetic_data.py +0 -0
  72. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai.egg-info/dependency_links.txt +0 -0
  73. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai.egg-info/requires.txt +0 -0
  74. {select_ai-1.0.0rc1 → select_ai-1.1.0}/src/select_ai.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: select_ai
3
- Version: 1.0.0rc1
3
+ Version: 1.1.0
4
4
  Summary: Select AI for Python
5
5
  Author-email: Abhishek Singh <abhishek.o.singh@oracle.com>
6
6
  Maintainer-email: Abhishek Singh <abhishek.o.singh@oracle.com>
@@ -46,6 +46,10 @@ Run
46
46
  python3 -m pip install select_ai
47
47
  ```
48
48
 
49
+ ## Documentation
50
+
51
+ See [Select AI for Python documentation][documentation]
52
+
49
53
  ## Samples
50
54
 
51
55
  Examples can be found in the [/samples][samples] directory
@@ -114,6 +118,7 @@ Released under the Universal Permissive License v1.0 as shown at
114
118
  <https://oss.oracle.com/licenses/upl/>.
115
119
 
116
120
  [contributing]: https://github.com/oracle/python-select-ai/blob/main/CONTRIBUTING.md
121
+ [documentation]: https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/pysai/
117
122
  [ghdiscussions]: https://github.com/oracle/python-select-ai/discussions
118
123
  [ghissues]: https://github.com/oracle/python-select-ai/issues
119
124
  [samples]: https://github.com/oracle/python-select-ai/tree/main/samples
@@ -13,6 +13,10 @@ Run
13
13
  python3 -m pip install select_ai
14
14
  ```
15
15
 
16
+ ## Documentation
17
+
18
+ See [Select AI for Python documentation][documentation]
19
+
16
20
  ## Samples
17
21
 
18
22
  Examples can be found in the [/samples][samples] directory
@@ -81,6 +85,7 @@ Released under the Universal Permissive License v1.0 as shown at
81
85
  <https://oss.oracle.com/licenses/upl/>.
82
86
 
83
87
  [contributing]: https://github.com/oracle/python-select-ai/blob/main/CONTRIBUTING.md
88
+ [documentation]: https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/pysai/
84
89
  [ghdiscussions]: https://github.com/oracle/python-select-ai/discussions
85
90
  [ghissues]: https://github.com/oracle/python-select-ai/issues
86
91
  [samples]: https://github.com/oracle/python-select-ai/tree/main/samples
@@ -0,0 +1,36 @@
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
+ # -----------------------------------------------------------------------------
9
+ # async/vector_index_get_attributes.py
10
+ #
11
+ # Get vector index attributes
12
+ # -----------------------------------------------------------------------------
13
+
14
+ import asyncio
15
+ import os
16
+
17
+ import select_ai
18
+
19
+ user = os.getenv("SELECT_AI_USER")
20
+ password = os.getenv("SELECT_AI_PASSWORD")
21
+ dsn = os.getenv("SELECT_AI_DB_CONNECT_STRING")
22
+
23
+
24
+ async def main():
25
+ await select_ai.async_connect(user=user, password=password, dsn=dsn)
26
+
27
+ async_vector_index = select_ai.AsyncVectorIndex(
28
+ index_name="test_vector_index",
29
+ )
30
+ attributes = await async_vector_index.get_attributes()
31
+ print(attributes)
32
+ async_profile = await async_vector_index.get_profile()
33
+ print(async_profile)
34
+
35
+
36
+ asyncio.run(main())
@@ -0,0 +1,44 @@
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
+ # -----------------------------------------------------------------------------
9
+ # async/vector_index_update_attributes.py
10
+ #
11
+ # Update Vector index attributes
12
+ # -----------------------------------------------------------------------------
13
+
14
+ import asyncio
15
+ import os
16
+
17
+ import select_ai
18
+
19
+ user = os.getenv("SELECT_AI_USER")
20
+ password = os.getenv("SELECT_AI_PASSWORD")
21
+ dsn = os.getenv("SELECT_AI_DB_CONNECT_STRING")
22
+
23
+
24
+ async def main():
25
+ await select_ai.async_connect(user=user, password=password, dsn=dsn)
26
+ async_vector_index = select_ai.AsyncVectorIndex(
27
+ index_name="test_vector_index",
28
+ )
29
+
30
+ # Use vector_index.set_attributes to update a multiple attributes
31
+ updated_attributes = select_ai.OracleVectorIndexAttributes(
32
+ refresh_rate=1450,
33
+ )
34
+ await async_vector_index.set_attributes(attributes=updated_attributes)
35
+
36
+ # Use vector_index.set_attribute to update a single attribute
37
+ await async_vector_index.set_attribute(
38
+ attribute_name="similarity_threshold", attribute_value=0.5
39
+ )
40
+ attributes = await async_vector_index.get_attributes()
41
+ print(attributes)
42
+
43
+
44
+ asyncio.run(main())
@@ -0,0 +1,29 @@
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
+ # -----------------------------------------------------------------------------
9
+ # vector_index_get_attributes.py
10
+ #
11
+ # Gets attributes for a vector index
12
+ # -----------------------------------------------------------------------------
13
+
14
+ import os
15
+
16
+ import select_ai
17
+
18
+ user = os.getenv("SELECT_AI_USER")
19
+ password = os.getenv("SELECT_AI_PASSWORD")
20
+ dsn = os.getenv("SELECT_AI_DB_CONNECT_STRING")
21
+
22
+ select_ai.connect(user=user, password=password, dsn=dsn)
23
+
24
+ vector_index = select_ai.VectorIndex(
25
+ index_name="test_vector_index",
26
+ )
27
+
28
+ print(vector_index.get_attributes())
29
+ print(vector_index.get_profile())
@@ -0,0 +1,36 @@
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
+ # -----------------------------------------------------------------------------
9
+ # vector_index_update_attributes.py
10
+ #
11
+ # Update attributes for a vector index
12
+ # -----------------------------------------------------------------------------
13
+
14
+ import os
15
+
16
+ import select_ai
17
+
18
+ user = os.getenv("SELECT_AI_USER")
19
+ password = os.getenv("SELECT_AI_PASSWORD")
20
+ dsn = os.getenv("SELECT_AI_DB_CONNECT_STRING")
21
+ select_ai.connect(user=user, password=password, dsn=dsn)
22
+ vector_index = select_ai.VectorIndex(
23
+ index_name="test_vector_index",
24
+ )
25
+
26
+ # Use vector_index.set_attributes to update a multiple attributes
27
+ updated_attributes = select_ai.OracleVectorIndexAttributes(
28
+ refresh_rate=1450,
29
+ )
30
+ vector_index.set_attributes(attributes=updated_attributes)
31
+
32
+ # Use vector_index.set_attribute to update a single attribute
33
+ vector_index.set_attribute(
34
+ attribute_name="similarity_threshold", attribute_value=0.5
35
+ )
36
+ print(vector_index.get_attributes())
@@ -21,7 +21,11 @@ import oracledb
21
21
  import pandas
22
22
 
23
23
  from select_ai.action import Action
24
- from select_ai.base_profile import BaseProfile, ProfileAttributes
24
+ from select_ai.base_profile import (
25
+ BaseProfile,
26
+ ProfileAttributes,
27
+ no_data_for_prompt,
28
+ )
25
29
  from select_ai.conversation import AsyncConversation
26
30
  from select_ai.db import async_cursor, async_get_connection
27
31
  from select_ai.errors import ProfileExistsError, ProfileNotFoundError
@@ -347,10 +351,10 @@ class AsyncProfile(BaseProfile):
347
351
  result = await data.read()
348
352
  else:
349
353
  result = None
350
- if action == Action.RUNSQL and result:
354
+ if action == Action.RUNSQL:
355
+ if no_data_for_prompt(result): # empty dataframe
356
+ return pandas.DataFrame()
351
357
  return pandas.DataFrame(json.loads(result))
352
- elif action == Action.RUNSQL:
353
- return pandas.DataFrame()
354
358
  else:
355
359
  return result
356
360
 
@@ -59,6 +59,7 @@ class ProfileAttributes(SelectAIDataClass):
59
59
  constraints: Optional[str] = None
60
60
  conversation: Optional[bool] = None
61
61
  credential_name: Optional[str] = None
62
+ enable_custom_source_uri: Optional[bool] = None
62
63
  enable_sources: Optional[bool] = None
63
64
  enable_source_offsets: Optional[bool] = None
64
65
  enforce_object_list: Optional[bool] = None
@@ -182,3 +183,11 @@ class BaseProfile(ABC):
182
183
  f"{self.__class__.__name__}(profile_name={self.profile_name}, "
183
184
  f"attributes={self.attributes}, description={self.description})"
184
185
  )
186
+
187
+
188
+ def no_data_for_prompt(result) -> bool:
189
+ if result is None:
190
+ return True
191
+ if result == "No data found for the prompt.":
192
+ return True
193
+ return False
@@ -15,7 +15,11 @@ import pandas
15
15
 
16
16
  from select_ai import Conversation
17
17
  from select_ai.action import Action
18
- from select_ai.base_profile import BaseProfile, ProfileAttributes
18
+ from select_ai.base_profile import (
19
+ BaseProfile,
20
+ ProfileAttributes,
21
+ no_data_for_prompt,
22
+ )
19
23
  from select_ai.db import cursor
20
24
  from select_ai.errors import ProfileExistsError, ProfileNotFoundError
21
25
  from select_ai.provider import Provider
@@ -319,10 +323,10 @@ class Profile(BaseProfile):
319
323
  result = data.read()
320
324
  else:
321
325
  result = None
322
- if action == Action.RUNSQL and result:
326
+ if action == Action.RUNSQL:
327
+ if no_data_for_prompt(result): # empty dataframe
328
+ return pandas.DataFrame()
323
329
  return pandas.DataFrame(json.loads(result))
324
- elif action == Action.RUNSQL:
325
- return pandas.DataFrame()
326
330
  else:
327
331
  return result
328
332
 
@@ -17,7 +17,7 @@ from select_ai._abc import SelectAIDataClass
17
17
  from select_ai._enums import StrEnum
18
18
  from select_ai.async_profile import AsyncProfile
19
19
  from select_ai.db import async_cursor, cursor
20
- from select_ai.errors import VectorIndexNotFoundError
20
+ from select_ai.errors import ProfileNotFoundError, VectorIndexNotFoundError
21
21
  from select_ai.profile import Profile
22
22
  from select_ai.sql import (
23
23
  GET_USER_VECTOR_INDEX_ATTRIBUTES,
@@ -89,9 +89,21 @@ class VectorIndexAttributes(SelectAIDataClass):
89
89
  vector_table_name: Optional[str] = None
90
90
  pipeline_name: Optional[str] = None
91
91
 
92
- def json(self, exclude_null=True):
92
+ def json(self, exclude_null=True, for_update=False):
93
93
  attributes = self.dict(exclude_null=exclude_null)
94
94
  attributes.pop("pipeline_name", None)
95
+ # Currently, the following are unmodifiable
96
+ unmodifiable = [
97
+ "location",
98
+ "chunk_size",
99
+ "chunk_overlap",
100
+ "vector_dimension",
101
+ "vector_table_name",
102
+ "vector_distance_metric",
103
+ ]
104
+ if for_update:
105
+ for key in unmodifiable:
106
+ attributes.pop(key, None)
95
107
  return json.dumps(attributes)
96
108
 
97
109
  @classmethod
@@ -113,7 +125,7 @@ class _BaseVectorIndex(ABC):
113
125
 
114
126
  def __init__(
115
127
  self,
116
- profile: BaseProfile = None,
128
+ profile: Optional[BaseProfile] = None,
117
129
  index_name: Optional[str] = None,
118
130
  description: Optional[str] = None,
119
131
  attributes: Optional[VectorIndexAttributes] = None,
@@ -159,7 +171,9 @@ class VectorIndex(_BaseVectorIndex):
159
171
  :raises: VectorIndexNotFoundError
160
172
  """
161
173
  with cursor() as cr:
162
- cr.execute(GET_USER_VECTOR_INDEX_ATTRIBUTES, index_name=index_name)
174
+ cr.execute(
175
+ GET_USER_VECTOR_INDEX_ATTRIBUTES, index_name=index_name.upper()
176
+ )
163
177
  attributes = cr.fetchall()
164
178
  if attributes:
165
179
  post_processed_attributes = {}
@@ -248,10 +262,18 @@ class VectorIndex(_BaseVectorIndex):
248
262
 
249
263
  """
250
264
  with cursor() as cr:
251
- cr.callproc(
252
- "DBMS_CLOUD_AI.ENABLE_VECTOR_INDEX",
253
- keyword_parameters={"index_name": self.index_name},
254
- )
265
+ try:
266
+ cr.callproc(
267
+ "DBMS_CLOUD_AI.ENABLE_VECTOR_INDEX",
268
+ keyword_parameters={"index_name": self.index_name},
269
+ )
270
+ except oracledb.Error as e:
271
+ (error,) = e.args
272
+ # ORA-20000: Vector Index is already in the desired status
273
+ if error.code == 20000:
274
+ pass
275
+ else:
276
+ raise
255
277
 
256
278
  def disable(self):
257
279
  """This procedure disables a vector index object in the current
@@ -263,16 +285,49 @@ class VectorIndex(_BaseVectorIndex):
263
285
  :return: None
264
286
  :raises: oracledb.DatabaseError
265
287
  """
288
+ with cursor() as cr:
289
+ try:
290
+ cr.callproc(
291
+ "DBMS_CLOUD_AI.DISABLE_VECTOR_INDEX",
292
+ keyword_parameters={"index_name": self.index_name},
293
+ )
294
+ except oracledb.Error as e:
295
+ (error,) = e.args
296
+ # ORA-20000: Vector Index is already in the desired status
297
+ if error.code == 20000:
298
+ pass
299
+ else:
300
+ raise
301
+
302
+ def set_attribute(
303
+ self,
304
+ attribute_name: str,
305
+ attribute_value: Union[str, int, float],
306
+ ):
307
+ """
308
+ This procedure updates an existing vector store index with a specified
309
+ value of the vector index attribute.
310
+
311
+ :param str attribute_name: Custom attribute name
312
+ :param Union[str, int, float] attribute_value: Attribute Value
313
+
314
+ """
315
+ setattr(self.attributes, attribute_name, attribute_value)
316
+ parameters = {
317
+ "index_name": self.index_name,
318
+ "attribute_name": attribute_name,
319
+ "attribute_value": attribute_value,
320
+ }
266
321
  with cursor() as cr:
267
322
  cr.callproc(
268
- "DBMS_CLOUD_AI.DISABLE_VECTOR_INDEX",
269
- keyword_parameters={"index_name": self.index_name},
323
+ "DBMS_CLOUD_AI.UPDATE_VECTOR_INDEX",
324
+ keyword_parameters=parameters,
270
325
  )
271
326
 
272
327
  def set_attributes(
273
328
  self,
274
- attribute_name: str,
275
- attribute_value: Union[str, int, float],
329
+ attribute_name: Optional[str] = None,
330
+ attribute_value: Optional[Union[str, int, float]] = None,
276
331
  attributes: VectorIndexAttributes = None,
277
332
  ):
278
333
  """
@@ -283,8 +338,8 @@ class VectorIndex(_BaseVectorIndex):
283
338
 
284
339
  :param str attribute_name: Custom attribute name
285
340
  :param Union[str, int, float] attribute_value: Attribute Value
286
- :param VectorIndexAttributes attributes: Specify multiple attributes
287
- to update in a single API invocation
341
+ :param select_ai.VectorIndexAttributes attributes: Use this to
342
+ update multiple attribute values
288
343
  :return: None
289
344
  :raises: oracledb.DatabaseError
290
345
  """
@@ -297,12 +352,12 @@ class VectorIndex(_BaseVectorIndex):
297
352
 
298
353
  parameters = {"index_name": self.index_name}
299
354
  if attributes:
300
- parameters["attributes"] = attributes.json()
355
+ parameters["attributes"] = attributes.json(for_update=True)
301
356
  self.attributes = attributes
302
357
  else:
303
358
  setattr(self.attributes, attribute_name, attribute_value)
304
- parameters["attributes_name"] = attribute_name
305
- parameters["attributes_value"] = attribute_value
359
+ parameters["attribute_name"] = attribute_name
360
+ parameters["attribute_value"] = attribute_value
306
361
 
307
362
  with cursor() as cr:
308
363
  cr.callproc(
@@ -318,6 +373,16 @@ class VectorIndex(_BaseVectorIndex):
318
373
  """
319
374
  return self._get_attributes(self.index_name)
320
375
 
376
+ def get_profile(self) -> Profile:
377
+ """Get Profile object linked to this vector index
378
+
379
+ :return: select_ai.Profile
380
+ :raises: ProfileNotFoundError
381
+ """
382
+ attributes = self._get_attributes(index_name=self.index_name)
383
+ profile = Profile(profile_name=attributes.profile_name)
384
+ return profile
385
+
321
386
  @classmethod
322
387
  def list(cls, index_name_pattern: str = ".*") -> Iterator["VectorIndex"]:
323
388
  """List Vector Indexes
@@ -340,11 +405,15 @@ class VectorIndex(_BaseVectorIndex):
340
405
  else:
341
406
  description = None
342
407
  attributes = cls._get_attributes(index_name=index_name)
408
+ try:
409
+ profile = Profile(profile_name=attributes.profile_name)
410
+ except ProfileNotFoundError:
411
+ profile = None
343
412
  yield cls(
344
413
  index_name=index_name,
345
414
  description=description,
346
415
  attributes=attributes,
347
- profile=Profile(profile_name=attributes.profile_name),
416
+ profile=profile,
348
417
  )
349
418
 
350
419
 
@@ -368,7 +437,7 @@ class AsyncVectorIndex(_BaseVectorIndex):
368
437
  """
369
438
  async with async_cursor() as cr:
370
439
  await cr.execute(
371
- GET_USER_VECTOR_INDEX_ATTRIBUTES, index_name=index_name
440
+ GET_USER_VECTOR_INDEX_ATTRIBUTES, index_name=index_name.upper()
372
441
  )
373
442
  attributes = await cr.fetchall()
374
443
  if attributes:
@@ -457,10 +526,18 @@ class AsyncVectorIndex(_BaseVectorIndex):
457
526
 
458
527
  """
459
528
  async with async_cursor() as cr:
460
- await cr.callproc(
461
- "DBMS_CLOUD_AI.ENABLE_VECTOR_INDEX",
462
- keyword_parameters={"index_name": self.index_name},
463
- )
529
+ try:
530
+ await cr.callproc(
531
+ "DBMS_CLOUD_AI.ENABLE_VECTOR_INDEX",
532
+ keyword_parameters={"index_name": self.index_name},
533
+ )
534
+ except oracledb.DatabaseError as e:
535
+ (error,) = e.args
536
+ # ORA-20000: Vector Index is already in the desired status
537
+ if error.code == 20000:
538
+ pass
539
+ else:
540
+ raise
464
541
 
465
542
  async def disable(self) -> None:
466
543
  """This procedure disables a vector index object in the current
@@ -472,16 +549,46 @@ class AsyncVectorIndex(_BaseVectorIndex):
472
549
  :return: None
473
550
  :raises: oracledb.DatabaseError
474
551
  """
552
+ async with async_cursor() as cr:
553
+ try:
554
+ await cr.callproc(
555
+ "DBMS_CLOUD_AI.DISABLE_VECTOR_INDEX",
556
+ keyword_parameters={"index_name": self.index_name},
557
+ )
558
+ except oracledb.Error as e:
559
+ (error,) = e.args
560
+ if error.code == 20000:
561
+ pass
562
+ else:
563
+ raise
564
+
565
+ async def set_attribute(
566
+ self, attribute_name: str, attribute_value: Union[str, int, float]
567
+ ) -> None:
568
+ """
569
+ This procedure updates an existing vector store index with a specified
570
+ value of the vector index attribute.
571
+
572
+ :param str attribute_name: Custom attribute name
573
+ :param Union[str, int, float] attribute_value: Attribute Value
574
+
575
+ """
576
+ parameters = {
577
+ "index_name": self.index_name,
578
+ "attribute_name": attribute_name,
579
+ "attribute_value": attribute_value,
580
+ }
581
+ setattr(self.attributes, attribute_name, attribute_value)
475
582
  async with async_cursor() as cr:
476
583
  await cr.callproc(
477
- "DBMS_CLOUD_AI.DISABLE_VECTOR_INDEX",
478
- keyword_parameters={"index_name": self.index_name},
584
+ "DBMS_CLOUD_AI.UPDATE_VECTOR_INDEX",
585
+ keyword_parameters=parameters,
479
586
  )
480
587
 
481
588
  async def set_attributes(
482
589
  self,
483
- attribute_name: str,
484
- attribute_value: Union[str, int],
590
+ attribute_name: Optional[str] = None,
591
+ attribute_value: Optional[Union[str, int, float]] = None,
485
592
  attributes: VectorIndexAttributes = None,
486
593
  ) -> None:
487
594
  """
@@ -492,8 +599,8 @@ class AsyncVectorIndex(_BaseVectorIndex):
492
599
 
493
600
  :param str attribute_name: Custom attribute name
494
601
  :param Union[str, int, float] attribute_value: Attribute Value
495
- :param VectorIndexAttributes attributes: Specify multiple attributes
496
- to update in a single API invocation
602
+ :param select_ai.VectorIndexAttributes attributes: Use this to
603
+ update multiple attribute values
497
604
  :return: None
498
605
  :raises: oracledb.DatabaseError
499
606
  """
@@ -506,11 +613,11 @@ class AsyncVectorIndex(_BaseVectorIndex):
506
613
  parameters = {"index_name": self.index_name}
507
614
  if attributes:
508
615
  self.attributes = attributes
509
- parameters["attributes"] = attributes.json()
616
+ parameters["attributes"] = attributes.json(for_update=True)
510
617
  else:
511
618
  setattr(self.attributes, attribute_name, attribute_value)
512
- parameters["attributes_name"] = attribute_name
513
- parameters["attributes_value"] = attribute_value
619
+ parameters["attribute_name"] = attribute_name
620
+ parameters["attribute_value"] = attribute_value
514
621
 
515
622
  async with async_cursor() as cr:
516
623
  await cr.callproc(
@@ -526,6 +633,16 @@ class AsyncVectorIndex(_BaseVectorIndex):
526
633
  """
527
634
  return await self._get_attributes(index_name=self.index_name)
528
635
 
636
+ async def get_profile(self) -> AsyncProfile:
637
+ """Get AsyncProfile object linked to this vector index
638
+
639
+ :return: select_ai.AsyncProfile
640
+ :raises: ProfileNotFoundError
641
+ """
642
+ attributes = await self._get_attributes(index_name=self.index_name)
643
+ profile = await AsyncProfile(profile_name=attributes.profile_name)
644
+ return profile
645
+
529
646
  @classmethod
530
647
  async def list(
531
648
  cls, index_name_pattern: str = ".*"
@@ -552,11 +669,15 @@ class AsyncVectorIndex(_BaseVectorIndex):
552
669
  else:
553
670
  description = None
554
671
  attributes = await cls._get_attributes(index_name=index_name)
672
+ try:
673
+ profile = await AsyncProfile(
674
+ profile_name=attributes.profile_name,
675
+ )
676
+ except ProfileNotFoundError:
677
+ profile = None
555
678
  yield VectorIndex(
556
679
  index_name=index_name,
557
680
  description=description,
558
681
  attributes=attributes,
559
- profile=await AsyncProfile(
560
- profile_name=attributes.profile_name
561
- ),
682
+ profile=profile,
562
683
  )
@@ -5,4 +5,4 @@
5
5
  # http://oss.oracle.com/licenses/upl.
6
6
  # -----------------------------------------------------------------------------
7
7
 
8
- __version__ = "1.0.0rc1"
8
+ __version__ = "1.1.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: select_ai
3
- Version: 1.0.0rc1
3
+ Version: 1.1.0
4
4
  Summary: Select AI for Python
5
5
  Author-email: Abhishek Singh <abhishek.o.singh@oracle.com>
6
6
  Maintainer-email: Abhishek Singh <abhishek.o.singh@oracle.com>
@@ -46,6 +46,10 @@ Run
46
46
  python3 -m pip install select_ai
47
47
  ```
48
48
 
49
+ ## Documentation
50
+
51
+ See [Select AI for Python documentation][documentation]
52
+
49
53
  ## Samples
50
54
 
51
55
  Examples can be found in the [/samples][samples] directory
@@ -114,6 +118,7 @@ Released under the Universal Permissive License v1.0 as shown at
114
118
  <https://oss.oracle.com/licenses/upl/>.
115
119
 
116
120
  [contributing]: https://github.com/oracle/python-select-ai/blob/main/CONTRIBUTING.md
121
+ [documentation]: https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/pysai/
117
122
  [ghdiscussions]: https://github.com/oracle/python-select-ai/discussions
118
123
  [ghissues]: https://github.com/oracle/python-select-ai/issues
119
124
  [samples]: https://github.com/oracle/python-select-ai/tree/main/samples
@@ -22,8 +22,10 @@ samples/profile_show_sql.py
22
22
  samples/profiles_list.py
23
23
  samples/vector_index_create.py
24
24
  samples/vector_index_delete.py
25
+ samples/vector_index_get_attributes.py
25
26
  samples/vector_index_list.py
26
27
  samples/vector_index_rag.py
28
+ samples/vector_index_update_attributes.py
27
29
  samples/async/conversation_chat_session.py
28
30
  samples/async/conversations_list.py
29
31
  samples/async/create_ai_credential.py
@@ -42,8 +44,10 @@ samples/async/profile_sql_concurrent_tasks.py
42
44
  samples/async/profiles_list.py
43
45
  samples/async/vector_index_create.py
44
46
  samples/async/vector_index_delete.py
47
+ samples/async/vector_index_get_attributes.py
45
48
  samples/async/vector_index_list.py
46
49
  samples/async/vector_index_rag.py
50
+ samples/async/vector_index_update_attributes.py
47
51
  src/select_ai/__init__.py
48
52
  src/select_ai/_abc.py
49
53
  src/select_ai/_enums.py
File without changes
File without changes
File without changes
File without changes