uipath 2.0.41__py3-none-any.whl → 2.0.43__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 uipath might be problematic. Click here for more details.
- uipath/_cli/cli_pack.py +14 -2
- uipath/_services/_base_service.py +3 -0
- uipath/_services/actions_service.py +12 -5
- uipath/_services/assets_service.py +109 -60
- uipath/_services/buckets_service.py +334 -101
- uipath/_services/context_grounding_service.py +205 -112
- uipath/_uipath.py +13 -1
- uipath/_utils/_read_overwrites.py +141 -0
- uipath/models/context_grounding_index.py +1 -0
- uipath/models/exceptions.py +9 -2
- {uipath-2.0.41.dist-info → uipath-2.0.43.dist-info}/METADATA +1 -1
- {uipath-2.0.41.dist-info → uipath-2.0.43.dist-info}/RECORD +15 -14
- {uipath-2.0.41.dist-info → uipath-2.0.43.dist-info}/WHEEL +0 -0
- {uipath-2.0.41.dist-info → uipath-2.0.43.dist-info}/entry_points.txt +0 -0
- {uipath-2.0.41.dist-info → uipath-2.0.43.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from typing import Any, List, Optional
|
|
2
|
+
from typing import Any, List, Optional, Tuple, Union
|
|
3
3
|
|
|
4
|
+
import httpx
|
|
4
5
|
from pydantic import TypeAdapter
|
|
5
6
|
|
|
6
7
|
from .._config import Config
|
|
@@ -14,6 +15,7 @@ from ..models import IngestionInProgressException
|
|
|
14
15
|
from ..models.context_grounding import ContextGroundingQueryResponse
|
|
15
16
|
from ..models.context_grounding_index import ContextGroundingIndex
|
|
16
17
|
from ..tracing._traced import traced
|
|
18
|
+
from . import BucketsService
|
|
17
19
|
from ._base_service import BaseService
|
|
18
20
|
from .folder_service import FolderService
|
|
19
21
|
|
|
@@ -36,28 +38,136 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
36
38
|
config: Config,
|
|
37
39
|
execution_context: ExecutionContext,
|
|
38
40
|
folders_service: FolderService,
|
|
41
|
+
buckets_service: BucketsService,
|
|
39
42
|
) -> None:
|
|
40
43
|
self._folders_service = folders_service
|
|
44
|
+
self._buckets_service = buckets_service
|
|
41
45
|
super().__init__(config=config, execution_context=execution_context)
|
|
42
46
|
|
|
47
|
+
@traced(name="add_to_index", run_type="uipath")
|
|
48
|
+
def add_to_index(
|
|
49
|
+
self,
|
|
50
|
+
name: str,
|
|
51
|
+
content_type: str,
|
|
52
|
+
blob_file_path: str,
|
|
53
|
+
content: Optional[Union[str, bytes]] = None,
|
|
54
|
+
source_path: Optional[str] = None,
|
|
55
|
+
folder_key: Optional[str] = None,
|
|
56
|
+
folder_path: Optional[str] = None,
|
|
57
|
+
) -> None:
|
|
58
|
+
"""Add content to the index.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
name (str): The name of the index to add content to.
|
|
62
|
+
content_type (str): The type of content being added.
|
|
63
|
+
blob_file_path (str): The path where the blob will be stored in the storage bucket.
|
|
64
|
+
content (Optional[Union[str, bytes]]): The content to be added, either as a string or bytes.
|
|
65
|
+
source_path (Optional[str]): The source path of the content if it is being uploaded from a file.
|
|
66
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
67
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
68
|
+
|
|
69
|
+
Raises:
|
|
70
|
+
ValueError: If neither content nor source_path is provided, or if both are provided.
|
|
71
|
+
"""
|
|
72
|
+
if not (content or source_path):
|
|
73
|
+
raise ValueError("Content or source_path is required")
|
|
74
|
+
if content and source_path:
|
|
75
|
+
raise ValueError("Content and source_path are mutually exclusive")
|
|
76
|
+
|
|
77
|
+
index = self.retrieve(name=name, folder_key=folder_key, folder_path=folder_path)
|
|
78
|
+
bucket_name, bucket_folder_path = self._extract_bucket_info(index)
|
|
79
|
+
if source_path:
|
|
80
|
+
self._buckets_service.upload(
|
|
81
|
+
name=bucket_name,
|
|
82
|
+
blob_file_path=blob_file_path,
|
|
83
|
+
source_path=source_path,
|
|
84
|
+
folder_path=bucket_folder_path,
|
|
85
|
+
content_type=content_type,
|
|
86
|
+
)
|
|
87
|
+
else:
|
|
88
|
+
self._buckets_service.upload_from_memory(
|
|
89
|
+
name=bucket_name,
|
|
90
|
+
content=content,
|
|
91
|
+
blob_file_path=blob_file_path,
|
|
92
|
+
folder_path=bucket_folder_path,
|
|
93
|
+
content_type=content_type,
|
|
94
|
+
)
|
|
95
|
+
self.ingest_data(index, folder_key=folder_key, folder_path=folder_path)
|
|
96
|
+
|
|
97
|
+
@traced(name="add_to_index", run_type="uipath")
|
|
98
|
+
async def add_to_index_async(
|
|
99
|
+
self,
|
|
100
|
+
name: str,
|
|
101
|
+
content_type: str,
|
|
102
|
+
blob_file_path: str,
|
|
103
|
+
content: Optional[Union[str, bytes]] = None,
|
|
104
|
+
source_path: Optional[str] = None,
|
|
105
|
+
folder_key: Optional[str] = None,
|
|
106
|
+
folder_path: Optional[str] = None,
|
|
107
|
+
) -> None:
|
|
108
|
+
"""Asynchronously add content to the index.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
name (str): The name of the index to add content to.
|
|
112
|
+
content_type (str): The type of content being added.
|
|
113
|
+
blob_file_path (str): The path where the blob will be stored in the storage bucket.
|
|
114
|
+
content (Optional[Union[str, bytes]]): The content to be added, either as a string or bytes.
|
|
115
|
+
source_path (Optional[str]): The source path of the content if it is being uploaded from a file.
|
|
116
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
117
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
ValueError: If neither content nor source_path is provided, or if both are provided.
|
|
121
|
+
"""
|
|
122
|
+
if not (content or source_path):
|
|
123
|
+
raise ValueError("Content or source_path is required")
|
|
124
|
+
if content and source_path:
|
|
125
|
+
raise ValueError("Content and source_path are mutually exclusive")
|
|
126
|
+
|
|
127
|
+
index = await self.retrieve_async(
|
|
128
|
+
name=name, folder_key=folder_key, folder_path=folder_path
|
|
129
|
+
)
|
|
130
|
+
bucket_name, bucket_folder_path = self._extract_bucket_info(index)
|
|
131
|
+
if source_path:
|
|
132
|
+
await self._buckets_service.upload_async(
|
|
133
|
+
name=bucket_name,
|
|
134
|
+
blob_file_path=blob_file_path,
|
|
135
|
+
source_path=source_path,
|
|
136
|
+
folder_path=bucket_folder_path,
|
|
137
|
+
content_type=content_type,
|
|
138
|
+
)
|
|
139
|
+
else:
|
|
140
|
+
await self._buckets_service.upload_from_memory_async(
|
|
141
|
+
name=bucket_name,
|
|
142
|
+
content=content, # type: ignore
|
|
143
|
+
blob_file_path=blob_file_path,
|
|
144
|
+
folder_path=bucket_folder_path,
|
|
145
|
+
content_type=content_type,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
await self.ingest_data_async(
|
|
149
|
+
index, folder_key=folder_key, folder_path=folder_path
|
|
150
|
+
)
|
|
151
|
+
|
|
43
152
|
@traced(name="contextgrounding_retrieve", run_type="uipath")
|
|
44
153
|
def retrieve(
|
|
45
154
|
self,
|
|
46
155
|
name: str,
|
|
47
156
|
folder_key: Optional[str] = None,
|
|
48
157
|
folder_path: Optional[str] = None,
|
|
49
|
-
) ->
|
|
158
|
+
) -> ContextGroundingIndex:
|
|
50
159
|
"""Retrieve context grounding index information by its name.
|
|
51
160
|
|
|
52
|
-
This method fetches details about a specific context index, which can be
|
|
53
|
-
used to understand what type of contextual information is available for
|
|
54
|
-
automation processes.
|
|
55
|
-
|
|
56
161
|
Args:
|
|
57
162
|
name (str): The name of the context index to retrieve.
|
|
163
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
164
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
58
165
|
|
|
59
166
|
Returns:
|
|
60
|
-
|
|
167
|
+
ContextGroundingIndex: The index information, including its configuration and metadata if found.
|
|
168
|
+
|
|
169
|
+
Raises:
|
|
170
|
+
Exception: If no index with the given name is found.
|
|
61
171
|
"""
|
|
62
172
|
spec = self._retrieve_spec(
|
|
63
173
|
name,
|
|
@@ -71,14 +181,14 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
71
181
|
params=spec.params,
|
|
72
182
|
headers=spec.headers,
|
|
73
183
|
).json()
|
|
74
|
-
|
|
75
|
-
(
|
|
184
|
+
try:
|
|
185
|
+
return next(
|
|
76
186
|
ContextGroundingIndex.model_validate(item)
|
|
77
187
|
for item in response["value"]
|
|
78
188
|
if item["name"] == name
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
|
|
189
|
+
)
|
|
190
|
+
except StopIteration as e:
|
|
191
|
+
raise Exception("ContextGroundingIndex not found") from e
|
|
82
192
|
|
|
83
193
|
@traced(name="contextgrounding_retrieve", run_type="uipath")
|
|
84
194
|
async def retrieve_async(
|
|
@@ -86,19 +196,19 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
86
196
|
name: str,
|
|
87
197
|
folder_key: Optional[str] = None,
|
|
88
198
|
folder_path: Optional[str] = None,
|
|
89
|
-
) ->
|
|
90
|
-
"""
|
|
91
|
-
|
|
92
|
-
This method fetches details about a specific context index, which can be
|
|
93
|
-
used to understand what type of contextual information is available for
|
|
94
|
-
automation processes.
|
|
199
|
+
) -> ContextGroundingIndex:
|
|
200
|
+
"""Asynchronously retrieve context grounding index information by its name.
|
|
95
201
|
|
|
96
202
|
Args:
|
|
97
203
|
name (str): The name of the context index to retrieve.
|
|
204
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
205
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
98
206
|
|
|
99
207
|
Returns:
|
|
100
|
-
|
|
208
|
+
ContextGroundingIndex: The index information, including its configuration and metadata if found.
|
|
101
209
|
|
|
210
|
+
Raises:
|
|
211
|
+
Exception: If no index with the given name is found.
|
|
102
212
|
"""
|
|
103
213
|
spec = self._retrieve_spec(
|
|
104
214
|
name,
|
|
@@ -111,16 +221,17 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
111
221
|
spec.method,
|
|
112
222
|
spec.endpoint,
|
|
113
223
|
params=spec.params,
|
|
224
|
+
headers=spec.headers,
|
|
114
225
|
)
|
|
115
226
|
).json()
|
|
116
|
-
|
|
117
|
-
(
|
|
227
|
+
try:
|
|
228
|
+
return next(
|
|
118
229
|
ContextGroundingIndex.model_validate(item)
|
|
119
230
|
for item in response["value"]
|
|
120
231
|
if item["name"] == name
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
|
|
232
|
+
)
|
|
233
|
+
except StopIteration as e:
|
|
234
|
+
raise Exception("ContextGroundingIndex not found") from e
|
|
124
235
|
|
|
125
236
|
@traced(name="contextgrounding_retrieve_by_id", run_type="uipath")
|
|
126
237
|
def retrieve_by_id(
|
|
@@ -136,6 +247,8 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
136
247
|
|
|
137
248
|
Args:
|
|
138
249
|
id (str): The unique identifier of the context index.
|
|
250
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
251
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
139
252
|
|
|
140
253
|
Returns:
|
|
141
254
|
Any: The index information, including its configuration and metadata.
|
|
@@ -166,10 +279,11 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
166
279
|
|
|
167
280
|
Args:
|
|
168
281
|
id (str): The unique identifier of the context index.
|
|
282
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
283
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
169
284
|
|
|
170
285
|
Returns:
|
|
171
286
|
Any: The index information, including its configuration and metadata.
|
|
172
|
-
|
|
173
287
|
"""
|
|
174
288
|
spec = self._retrieve_by_id_spec(
|
|
175
289
|
id,
|
|
@@ -282,82 +396,6 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
282
396
|
response.json()
|
|
283
397
|
)
|
|
284
398
|
|
|
285
|
-
@traced(name="contextgrounding_get_or_create_index", run_type="uipath")
|
|
286
|
-
def get_or_create_index(
|
|
287
|
-
self,
|
|
288
|
-
name: str,
|
|
289
|
-
*,
|
|
290
|
-
description: Optional[str] = None,
|
|
291
|
-
storage_bucket_name: str,
|
|
292
|
-
file_name_glob: Optional[str] = None,
|
|
293
|
-
storage_bucket_folder_path: Optional[str] = None,
|
|
294
|
-
folder_key: Optional[str] = None,
|
|
295
|
-
folder_path: Optional[str] = None,
|
|
296
|
-
) -> ContextGroundingIndex:
|
|
297
|
-
spec = self._create_spec(
|
|
298
|
-
name,
|
|
299
|
-
description,
|
|
300
|
-
storage_bucket_name,
|
|
301
|
-
file_name_glob,
|
|
302
|
-
storage_bucket_folder_path,
|
|
303
|
-
folder_key=folder_key,
|
|
304
|
-
folder_path=folder_path,
|
|
305
|
-
)
|
|
306
|
-
index = self.retrieve(
|
|
307
|
-
name=name,
|
|
308
|
-
folder_key=folder_key,
|
|
309
|
-
folder_path=folder_path,
|
|
310
|
-
)
|
|
311
|
-
if index:
|
|
312
|
-
return index
|
|
313
|
-
|
|
314
|
-
response = self.request(
|
|
315
|
-
spec.method,
|
|
316
|
-
spec.endpoint,
|
|
317
|
-
content=spec.content,
|
|
318
|
-
headers=spec.headers,
|
|
319
|
-
).json()
|
|
320
|
-
return ContextGroundingIndex.model_validate(response)
|
|
321
|
-
|
|
322
|
-
@traced(name="contextgrounding_get_or_create_index", run_type="uipath")
|
|
323
|
-
async def get_or_create_index_async(
|
|
324
|
-
self,
|
|
325
|
-
name: str,
|
|
326
|
-
*,
|
|
327
|
-
description: Optional[str] = None,
|
|
328
|
-
storage_bucket_name: str,
|
|
329
|
-
file_name_glob: Optional[str] = None,
|
|
330
|
-
storage_bucket_folder_path: Optional[str] = None,
|
|
331
|
-
folder_key: Optional[str] = None,
|
|
332
|
-
folder_path: Optional[str] = None,
|
|
333
|
-
) -> ContextGroundingIndex:
|
|
334
|
-
index = await self.retrieve_async(
|
|
335
|
-
name=name,
|
|
336
|
-
folder_key=folder_key,
|
|
337
|
-
folder_path=folder_path,
|
|
338
|
-
)
|
|
339
|
-
if index:
|
|
340
|
-
return index
|
|
341
|
-
|
|
342
|
-
spec = self._create_spec(
|
|
343
|
-
name,
|
|
344
|
-
description,
|
|
345
|
-
storage_bucket_name,
|
|
346
|
-
file_name_glob,
|
|
347
|
-
storage_bucket_folder_path,
|
|
348
|
-
folder_key=folder_key,
|
|
349
|
-
folder_path=folder_path,
|
|
350
|
-
)
|
|
351
|
-
response = (
|
|
352
|
-
await self.request_async(
|
|
353
|
-
spec.method,
|
|
354
|
-
spec.endpoint,
|
|
355
|
-
content=spec.content,
|
|
356
|
-
headers=spec.headers,
|
|
357
|
-
)
|
|
358
|
-
).json()
|
|
359
|
-
return ContextGroundingIndex.model_validate(response)
|
|
360
|
-
|
|
361
399
|
@traced(name="contextgrounding_ingest_data", run_type="uipath")
|
|
362
400
|
def ingest_data(
|
|
363
401
|
self,
|
|
@@ -365,6 +403,13 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
365
403
|
folder_key: Optional[str] = None,
|
|
366
404
|
folder_path: Optional[str] = None,
|
|
367
405
|
) -> None:
|
|
406
|
+
"""Ingest data into the context grounding index.
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
index (ContextGroundingIndex): The context grounding index to perform data ingestion.
|
|
410
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
411
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
412
|
+
"""
|
|
368
413
|
if not index.id:
|
|
369
414
|
return
|
|
370
415
|
spec = self._ingest_spec(
|
|
@@ -372,11 +417,18 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
372
417
|
folder_key=folder_key,
|
|
373
418
|
folder_path=folder_path,
|
|
374
419
|
)
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
420
|
+
try:
|
|
421
|
+
self.request(
|
|
422
|
+
spec.method,
|
|
423
|
+
spec.endpoint,
|
|
424
|
+
headers=spec.headers,
|
|
425
|
+
)
|
|
426
|
+
except httpx.HTTPStatusError as e:
|
|
427
|
+
if e.response.status_code != 409:
|
|
428
|
+
raise e
|
|
429
|
+
raise IngestionInProgressException(
|
|
430
|
+
index_name=index.name, search_operation=False
|
|
431
|
+
) from e
|
|
380
432
|
|
|
381
433
|
@traced(name="contextgrounding_ingest_data", run_type="uipath")
|
|
382
434
|
async def ingest_data_async(
|
|
@@ -385,6 +437,13 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
385
437
|
folder_key: Optional[str] = None,
|
|
386
438
|
folder_path: Optional[str] = None,
|
|
387
439
|
) -> None:
|
|
440
|
+
"""Asynchronously ingest data into the context grounding index.
|
|
441
|
+
|
|
442
|
+
Args:
|
|
443
|
+
index (ContextGroundingIndex): The context grounding index to perform data ingestion.
|
|
444
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
445
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
446
|
+
"""
|
|
388
447
|
if not index.id:
|
|
389
448
|
return
|
|
390
449
|
spec = self._ingest_spec(
|
|
@@ -392,11 +451,18 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
392
451
|
folder_key=folder_key,
|
|
393
452
|
folder_path=folder_path,
|
|
394
453
|
)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
454
|
+
try:
|
|
455
|
+
await self.request_async(
|
|
456
|
+
spec.method,
|
|
457
|
+
spec.endpoint,
|
|
458
|
+
headers=spec.headers,
|
|
459
|
+
)
|
|
460
|
+
except httpx.HTTPStatusError as e:
|
|
461
|
+
if e.response.status_code != 409:
|
|
462
|
+
raise e
|
|
463
|
+
raise IngestionInProgressException(
|
|
464
|
+
index_name=index.name, search_operation=False
|
|
465
|
+
) from e
|
|
400
466
|
|
|
401
467
|
@traced(name="contextgrounding_delete_index", run_type="uipath")
|
|
402
468
|
def delete_index(
|
|
@@ -405,6 +471,15 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
405
471
|
folder_key: Optional[str] = None,
|
|
406
472
|
folder_path: Optional[str] = None,
|
|
407
473
|
) -> None:
|
|
474
|
+
"""Delete a context grounding index.
|
|
475
|
+
|
|
476
|
+
This method removes the specified context grounding index from Orchestrator.
|
|
477
|
+
|
|
478
|
+
Args:
|
|
479
|
+
index (ContextGroundingIndex): The context grounding index to delete.
|
|
480
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
481
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
482
|
+
"""
|
|
408
483
|
if not index.id:
|
|
409
484
|
return
|
|
410
485
|
spec = self._delete_by_id_spec(
|
|
@@ -425,6 +500,15 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
425
500
|
folder_key: Optional[str] = None,
|
|
426
501
|
folder_path: Optional[str] = None,
|
|
427
502
|
) -> None:
|
|
503
|
+
"""Asynchronously delete a context grounding index.
|
|
504
|
+
|
|
505
|
+
This method removes the specified context grounding index from Orchestrator.
|
|
506
|
+
|
|
507
|
+
Args:
|
|
508
|
+
index (ContextGroundingIndex): The context grounding index to delete.
|
|
509
|
+
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
510
|
+
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
511
|
+
"""
|
|
428
512
|
if not index.id:
|
|
429
513
|
return
|
|
430
514
|
spec = self._delete_by_id_spec(
|
|
@@ -465,7 +549,10 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
465
549
|
return RequestSpec(
|
|
466
550
|
method="GET",
|
|
467
551
|
endpoint=Endpoint("/ecs_/v2/indexes"),
|
|
468
|
-
params={
|
|
552
|
+
params={
|
|
553
|
+
"$filter": f"Name eq '{name}'",
|
|
554
|
+
"$expand": "dataSource",
|
|
555
|
+
},
|
|
469
556
|
headers={
|
|
470
557
|
**header_folder(folder_key, None),
|
|
471
558
|
},
|
|
@@ -582,3 +669,9 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
582
669
|
raise ValueError("Folder key or folder path is required")
|
|
583
670
|
|
|
584
671
|
return folder_key
|
|
672
|
+
|
|
673
|
+
def _extract_bucket_info(self, index: ContextGroundingIndex) -> Tuple[str, str]:
|
|
674
|
+
try:
|
|
675
|
+
return index.data_source.bucketName, index.data_source.folder # type: ignore
|
|
676
|
+
except AttributeError as e:
|
|
677
|
+
raise Exception("Cannot extract bucket data from index") from e
|
uipath/_uipath.py
CHANGED
|
@@ -56,6 +56,7 @@ class UiPath:
|
|
|
56
56
|
elif error["loc"][0] == "secret":
|
|
57
57
|
raise SecretMissingError() from e
|
|
58
58
|
self._folders_service: Optional[FolderService] = None
|
|
59
|
+
self._buckets_service: Optional[BucketsService] = None
|
|
59
60
|
|
|
60
61
|
setup_logging(debug)
|
|
61
62
|
self._execution_context = ExecutionContext()
|
|
@@ -78,6 +79,10 @@ class UiPath:
|
|
|
78
79
|
|
|
79
80
|
@property
|
|
80
81
|
def buckets(self) -> BucketsService:
|
|
82
|
+
if not self._buckets_service:
|
|
83
|
+
self._buckets_service = BucketsService(
|
|
84
|
+
self._config, self._execution_context
|
|
85
|
+
)
|
|
81
86
|
return BucketsService(self._config, self._execution_context)
|
|
82
87
|
|
|
83
88
|
@property
|
|
@@ -88,8 +93,15 @@ class UiPath:
|
|
|
88
93
|
def context_grounding(self) -> ContextGroundingService:
|
|
89
94
|
if not self._folders_service:
|
|
90
95
|
self._folders_service = FolderService(self._config, self._execution_context)
|
|
96
|
+
if not self._buckets_service:
|
|
97
|
+
self._buckets_service = BucketsService(
|
|
98
|
+
self._config, self._execution_context
|
|
99
|
+
)
|
|
91
100
|
return ContextGroundingService(
|
|
92
|
-
self._config,
|
|
101
|
+
self._config,
|
|
102
|
+
self._execution_context,
|
|
103
|
+
self._folders_service,
|
|
104
|
+
self._buckets_service,
|
|
93
105
|
)
|
|
94
106
|
|
|
95
107
|
@property
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from contextlib import contextmanager
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, Dict, Generator, Optional, Tuple
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class OverwritesManager:
|
|
8
|
+
"""Manages overwrites for different resource types and methods.
|
|
9
|
+
|
|
10
|
+
This class handles reading and accessing bindings overwrites from a JSON file.
|
|
11
|
+
The overwrites are stored under the 'resourceOverwrites' key, where each key is a
|
|
12
|
+
resource key (e.g., 'asset.MyAssetKeyFromBindingsJson') and the value contains
|
|
13
|
+
'name' and 'folderPath' fields.
|
|
14
|
+
|
|
15
|
+
This is a singleton class to ensure only one instance exists throughout the application.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
_instance = None
|
|
19
|
+
_overwrites_file_path: Path = Path("uipath.json")
|
|
20
|
+
_overwrites: Dict[str, Any] = {}
|
|
21
|
+
|
|
22
|
+
def __new__(
|
|
23
|
+
cls, overwrites_file_path: Optional[Path] = None
|
|
24
|
+
) -> "OverwritesManager":
|
|
25
|
+
"""Create or return the singleton instance.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
overwrites_file_path: Optional path to the overwrites JSON file.
|
|
29
|
+
If not provided, defaults to 'uipath.json' in the project root.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
The singleton instance of OverwritesManager.
|
|
33
|
+
"""
|
|
34
|
+
if cls._instance is None:
|
|
35
|
+
cls._instance = super().__new__(cls)
|
|
36
|
+
cls._instance._overwrites_file_path = (
|
|
37
|
+
overwrites_file_path or cls._overwrites_file_path
|
|
38
|
+
)
|
|
39
|
+
cls._instance._read_overwrites_file()
|
|
40
|
+
elif (
|
|
41
|
+
overwrites_file_path
|
|
42
|
+
and overwrites_file_path != cls._instance._overwrites_file_path
|
|
43
|
+
):
|
|
44
|
+
# If a new file path is provided and it's different from the current one,
|
|
45
|
+
# update the path and re-read the file
|
|
46
|
+
cls._instance._overwrites_file_path = overwrites_file_path
|
|
47
|
+
cls._instance._read_overwrites_file()
|
|
48
|
+
return cls._instance
|
|
49
|
+
|
|
50
|
+
def _read_overwrites_file(self) -> None:
|
|
51
|
+
"""Read the overwrites JSON file and cache the data.
|
|
52
|
+
|
|
53
|
+
Raises:
|
|
54
|
+
FileNotFoundError: If the overwrites file doesn't exist.
|
|
55
|
+
json.JSONDecodeError: If the file contains invalid JSON.
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
with open(self._overwrites_file_path, "r") as f:
|
|
59
|
+
self._overwrites = json.load(f)
|
|
60
|
+
except FileNotFoundError:
|
|
61
|
+
self._overwrites = {}
|
|
62
|
+
|
|
63
|
+
def get_overwrite(
|
|
64
|
+
self, resource_type: str, resource_name: str
|
|
65
|
+
) -> Optional[Tuple[str, str]]:
|
|
66
|
+
"""Get an overwrite value for a specific resource.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
resource_type: The type of resource (e.g., 'process', 'asset').
|
|
70
|
+
resource_name: The name of the resource.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
A tuple of (name, folder_path) if found, None otherwise.
|
|
74
|
+
"""
|
|
75
|
+
overwrites = self._overwrites.get("resourceOverwrites", {})
|
|
76
|
+
key = f"{resource_type}.{resource_name}"
|
|
77
|
+
|
|
78
|
+
if key not in overwrites:
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
overwrite = overwrites[key]
|
|
82
|
+
return (
|
|
83
|
+
overwrite.get("name", resource_name),
|
|
84
|
+
overwrite.get("folderPath", ""),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def get_and_apply_overwrite(
|
|
88
|
+
self, resource_type: str, resource_name: str, folder_path: Optional[str] = None
|
|
89
|
+
) -> Tuple[str, str]:
|
|
90
|
+
"""Get and apply overwrites for a resource, falling back to provided values if no overwrites exist.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
resource_type: The type of resource (e.g., 'process', 'asset').
|
|
94
|
+
resource_name: The name of the resource.
|
|
95
|
+
folder_path: Optional folder path to use if no overwrite exists.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
A tuple of (name, folder_path) with overwritten values if available,
|
|
99
|
+
otherwise the original values.
|
|
100
|
+
"""
|
|
101
|
+
overwrite = self.get_overwrite(resource_type, resource_name)
|
|
102
|
+
if overwrite:
|
|
103
|
+
name, overwrite_folder_path = overwrite
|
|
104
|
+
# Only use overwrite folder path if no folder_path was provided
|
|
105
|
+
if folder_path is None:
|
|
106
|
+
folder_path = overwrite_folder_path
|
|
107
|
+
return name, folder_path
|
|
108
|
+
return resource_name, folder_path or ""
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@contextmanager
|
|
112
|
+
def read_resource_overwrites(
|
|
113
|
+
resource_type: str,
|
|
114
|
+
resource_name: str,
|
|
115
|
+
folder_path: Optional[str] = None,
|
|
116
|
+
overwrites_file_path: Optional[Path] = None,
|
|
117
|
+
) -> Generator[Tuple[str, str], None, None]:
|
|
118
|
+
"""Context manager for reading and applying resource overwrites.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
resource_type: The type of resource (e.g., 'process', 'asset').
|
|
122
|
+
resource_name: The name of the resource.
|
|
123
|
+
folder_path: Optional folder path to use if no overwrite exists.
|
|
124
|
+
overwrites_file_path: Optional path to the overwrites JSON file.
|
|
125
|
+
|
|
126
|
+
Yields:
|
|
127
|
+
A tuple of (name, folder_path) with overwritten values if available,
|
|
128
|
+
otherwise the original values.
|
|
129
|
+
|
|
130
|
+
Example:
|
|
131
|
+
```python
|
|
132
|
+
with read_resource_overwrites("asset", "MyAsset") as (name, folder_path):
|
|
133
|
+
# Use name and folder_path here
|
|
134
|
+
pass
|
|
135
|
+
```
|
|
136
|
+
"""
|
|
137
|
+
manager = OverwritesManager(overwrites_file_path)
|
|
138
|
+
try:
|
|
139
|
+
yield manager.get_and_apply_overwrite(resource_type, resource_name, folder_path)
|
|
140
|
+
finally:
|
|
141
|
+
pass
|
|
@@ -25,6 +25,7 @@ class ContextGroundingDataSource(BaseModel):
|
|
|
25
25
|
)
|
|
26
26
|
id: Optional[str] = Field(default=None, alias="id")
|
|
27
27
|
folder: Optional[str] = Field(default=None, alias="folder")
|
|
28
|
+
bucketName: Optional[str] = Field(default=None, alias="bucketName")
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
class ContextGroundingIndex(BaseModel):
|
uipath/models/exceptions.py
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
class IngestionInProgressException(Exception):
|
|
2
5
|
"""An exception that is triggered when a search is attempted on an index that is currently undergoing ingestion."""
|
|
3
6
|
|
|
4
|
-
def __init__(self, index_name):
|
|
5
|
-
|
|
7
|
+
def __init__(self, index_name: Optional[str], search_operation: bool = True):
|
|
8
|
+
index_name = index_name or "Unknown index name"
|
|
9
|
+
if search_operation:
|
|
10
|
+
self.message = f"index '{index_name}' cannot be searched during ingestion"
|
|
11
|
+
else:
|
|
12
|
+
self.message = f"index '{index_name}' is currently queued for ingestion"
|
|
6
13
|
super().__init__(self.message)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: uipath
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.43
|
|
4
4
|
Summary: Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools.
|
|
5
5
|
Project-URL: Homepage, https://uipath.com
|
|
6
6
|
Project-URL: Repository, https://github.com/UiPath/uipath-python
|