Skip to content

Commit 77c98b8

Browse files
authored
feat: platform - retrieve indexes across folders [ECS-1653] (#1419)
1 parent 7b01a15 commit 77c98b8

File tree

4 files changed

+448
-6
lines changed

4 files changed

+448
-6
lines changed

packages/uipath-platform/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath-platform"
3-
version = "0.0.15"
3+
version = "0.0.16"
44
description = "HTTP client library for programmatic access to UiPath Platform"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"

packages/uipath-platform/src/uipath/platform/context_grounding/_context_grounding_service.py

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,64 @@ async def add_to_index_async(
193193
index, folder_key=folder_key, folder_path=folder_path
194194
)
195195

196+
@traced(name="contextgrounding_retrieve_across_folders", run_type="uipath")
197+
def retrieve_across_folders(
198+
self,
199+
name: Optional[str] = None,
200+
) -> List[ContextGroundingIndex]:
201+
"""Retrieve all context grounding indexes across all folders.
202+
203+
This method fetches indexes from all folders without requiring a folder key.
204+
205+
Args:
206+
name (Optional[str]): Optional name filter. If provided, only indexes
207+
matching this name will be returned.
208+
209+
Returns:
210+
List[ContextGroundingIndex]: A list of indexes across all folders.
211+
"""
212+
spec = self._retrieve_across_folders_spec(name=name)
213+
214+
response = self.request(
215+
spec.method,
216+
spec.endpoint,
217+
params=spec.params,
218+
).json()
219+
220+
return [
221+
ContextGroundingIndex.model_validate(item) for item in response["value"]
222+
]
223+
224+
@traced(name="contextgrounding_retrieve_across_folders", run_type="uipath")
225+
async def retrieve_across_folders_async(
226+
self,
227+
name: Optional[str] = None,
228+
) -> List[ContextGroundingIndex]:
229+
"""Asynchronously retrieve all context grounding indexes across all folders.
230+
231+
This method fetches indexes from all folders without requiring a folder key.
232+
233+
Args:
234+
name (Optional[str]): Optional name filter. If provided, only indexes
235+
matching this name will be returned.
236+
237+
Returns:
238+
List[ContextGroundingIndex]: A list of indexes across all folders.
239+
"""
240+
spec = self._retrieve_across_folders_spec(name=name)
241+
242+
response = (
243+
await self.request_async(
244+
spec.method,
245+
spec.endpoint,
246+
params=spec.params,
247+
)
248+
).json()
249+
250+
return [
251+
ContextGroundingIndex.model_validate(item) for item in response["value"]
252+
]
253+
196254
@resource_override(resource_type="index")
197255
@traced(name="contextgrounding_retrieve", run_type="uipath")
198256
def retrieve(
@@ -203,6 +261,9 @@ def retrieve(
203261
) -> ContextGroundingIndex:
204262
"""Retrieve context grounding index information by its name.
205263
264+
If no folder_key or folder_path is provided and no folder context is
265+
configured, falls back to searching across all folders.
266+
206267
Args:
207268
name (str): The name of the context index to retrieve.
208269
folder_key (Optional[str]): The key of the folder where the index resides.
@@ -214,10 +275,17 @@ def retrieve(
214275
Raises:
215276
Exception: If no index with the given name is found.
216277
"""
278+
resolved_folder_key = self._resolve_folder_key(folder_key, folder_path)
279+
if not resolved_folder_key:
280+
indexes = self.retrieve_across_folders(name=name)
281+
try:
282+
return next(index for index in indexes if index.name == name)
283+
except StopIteration as e:
284+
raise Exception("ContextGroundingIndex not found") from e
285+
217286
spec = self._retrieve_spec(
218287
name,
219-
folder_key=folder_key,
220-
folder_path=folder_path,
288+
folder_key=resolved_folder_key,
221289
)
222290

223291
response = self.request(
@@ -245,6 +313,9 @@ async def retrieve_async(
245313
) -> ContextGroundingIndex:
246314
"""Asynchronously retrieve context grounding index information by its name.
247315
316+
If no folder_key or folder_path is provided and no folder context is
317+
configured, falls back to searching across all folders.
318+
248319
Args:
249320
name (str): The name of the context index to retrieve.
250321
folder_key (Optional[str]): The key of the folder where the index resides.
@@ -256,10 +327,17 @@ async def retrieve_async(
256327
Raises:
257328
Exception: If no index with the given name is found.
258329
"""
330+
resolved_folder_key = self._resolve_folder_key(folder_key, folder_path)
331+
if not resolved_folder_key:
332+
indexes = await self.retrieve_across_folders_async(name=name)
333+
try:
334+
return next(index for index in indexes if index.name == name)
335+
except StopIteration as e:
336+
raise Exception("ContextGroundingIndex not found") from e
337+
259338
spec = self._retrieve_spec(
260339
name,
261-
folder_key=folder_key,
262-
folder_path=folder_path,
340+
folder_key=resolved_folder_key,
263341
)
264342

265343
response = (
@@ -626,6 +704,7 @@ def start_batch_transform(
626704
if index and index.in_progress_ingestion():
627705
raise IngestionInProgressException(index_name=index_name)
628706
index_id = index.id
707+
folder_key = folder_key or index.folder_key
629708

630709
spec = self._batch_transform_creation_spec(
631710
index_id=index_id,
@@ -701,6 +780,7 @@ async def start_batch_transform_async(
701780
if index and index.in_progress_ingestion():
702781
raise IngestionInProgressException(index_name=index_name)
703782
index_id = index.id
783+
folder_key = folder_key or index.folder_key
704784

705785
spec = self._batch_transform_creation_spec(
706786
index_id=index_id,
@@ -1025,6 +1105,7 @@ def start_deep_rag(
10251105
if index and index.in_progress_ingestion():
10261106
raise IngestionInProgressException(index_name=index_name)
10271107
index_id = index.id
1108+
folder_key = folder_key or index.folder_key
10281109

10291110
spec = self._deep_rag_creation_spec(
10301111
index_id=index_id,
@@ -1087,6 +1168,7 @@ async def start_deep_rag_async(
10871168
if index and index.in_progress_ingestion():
10881169
raise IngestionInProgressException(index_name=index_name)
10891170
index_id = index.id
1171+
folder_key = folder_key or index.folder_key
10901172

10911173
spec = self._deep_rag_creation_spec(
10921174
index_id=index_id,
@@ -1220,6 +1302,8 @@ def search(
12201302
if index and index.in_progress_ingestion():
12211303
raise IngestionInProgressException(index_name=name)
12221304

1305+
folder_key = folder_key or index.folder_key
1306+
12231307
spec = self._search_spec(
12241308
name,
12251309
query,
@@ -1272,6 +1356,9 @@ async def search_async(
12721356
)
12731357
if index and index.in_progress_ingestion():
12741358
raise IngestionInProgressException(index_name=name)
1359+
1360+
folder_key = folder_key or index.folder_key
1361+
12751362
spec = self._search_spec(
12761363
name,
12771364
query,
@@ -1433,6 +1520,22 @@ def _ingest_spec(
14331520
},
14341521
)
14351522

1523+
def _retrieve_across_folders_spec(
1524+
self,
1525+
name: Optional[str] = None,
1526+
) -> RequestSpec:
1527+
params: Dict[str, str] = {
1528+
"$expand": "dataSource",
1529+
}
1530+
if name:
1531+
params["$filter"] = f"Name eq '{name}'"
1532+
1533+
return RequestSpec(
1534+
method="GET",
1535+
endpoint=Endpoint("/ecs_/v2/indexes/allacrossfolders"),
1536+
params=params,
1537+
)
1538+
14361539
def _retrieve_spec(
14371540
self,
14381541
name: str,

0 commit comments

Comments
 (0)