uipath 2.0.0.dev2__tar.gz → 2.0.0.dev3__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 uipath might be problematic. Click here for more details.
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/PKG-INFO +1 -1
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/pyproject.toml +1 -1
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/__init__.py +2 -0
- uipath-2.0.0.dev3/uipath/_models/context_grounding_index.py +60 -0
- uipath-2.0.0.dev3/uipath/_models/exceptions.py +6 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/__init__.py +2 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/buckets_service.py +68 -5
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/context_grounding_service.py +199 -15
- uipath-2.0.0.dev3/uipath/_services/folder_service.py +49 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_uipath.py +13 -1
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_utils/constants.py +5 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/.gitignore +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/README.md +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/__init__.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/README.md +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/__init__.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_auth/_auth_server.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_auth/_models.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_auth/_oidc_utils.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_auth/_portal_service.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_auth/_utils.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_auth/auth_config.json +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_auth/index.html +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_auth/localhost.crt +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_auth/localhost.key +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_runtime/_contracts.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_runtime/_logging.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_runtime/_runtime.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_templates/.psmdcp.template +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_templates/.rels.template +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_templates/[Content_Types].xml.template +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_templates/main.py.template +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_templates/package.nuspec.template +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_utils/_common.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_utils/_input_args.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/_utils/_parse_ast.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/cli_auth.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/cli_deploy.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/cli_init.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/cli_new.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/cli_pack.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/cli_publish.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/cli_run.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_cli/middlewares.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_config.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_execution_context.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_folder_context.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/action_schema.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/actions.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/assets.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/connections.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/context_grounding.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/interrupt_models.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/job.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/llm_gateway.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/processes.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_models/queues.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/_base_service.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/actions_service.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/api_client.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/assets_service.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/connections_service.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/connections_service.pyi +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/jobs_service.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/llm_gateway_service.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/processes_service.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_services/queues_service.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_utils/__init__.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_utils/_endpoint.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_utils/_infer_bindings.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_utils/_logs.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_utils/_request_override.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_utils/_request_spec.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/_utils/_user_agent.py +0 -0
- {uipath-2.0.0.dev2 → uipath-2.0.0.dev3}/uipath/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: uipath
|
|
3
|
-
Version: 2.0.0.
|
|
3
|
+
Version: 2.0.0.dev3
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "uipath"
|
|
3
|
-
version = "2.0.0.
|
|
3
|
+
version = "2.0.0.dev3"
|
|
4
4
|
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
|
|
5
5
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
6
6
|
requires-python = ">=3.9"
|
|
@@ -3,6 +3,7 @@ from .actions import Action
|
|
|
3
3
|
from .assets import UserAsset
|
|
4
4
|
from .connections import Connection, ConnectionToken
|
|
5
5
|
from .context_grounding import ContextGroundingQueryResponse
|
|
6
|
+
from .exceptions import IngestionInProgressException
|
|
6
7
|
from .interrupt_models import CreateAction, InvokeProcess, WaitAction, WaitJob
|
|
7
8
|
from .job import Job
|
|
8
9
|
from .processes import Process
|
|
@@ -32,4 +33,5 @@ __all__ = [
|
|
|
32
33
|
"WaitJob",
|
|
33
34
|
"WaitAction",
|
|
34
35
|
"CreateAction",
|
|
36
|
+
"IngestionInProgressException",
|
|
35
37
|
]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Any, List, Optional
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ContextGroundingField(BaseModel):
|
|
8
|
+
id: Optional[str] = Field(default=None, alias="id")
|
|
9
|
+
name: Optional[str] = Field(default=None, alias="name")
|
|
10
|
+
description: Optional[str] = Field(default=None, alias="description")
|
|
11
|
+
type: Optional[str] = Field(default=None, alias="type")
|
|
12
|
+
is_filterable: Optional[bool] = Field(default=None, alias="isFilterable")
|
|
13
|
+
searchable_type: Optional[str] = Field(default=None, alias="searchableType")
|
|
14
|
+
is_user_defined: Optional[bool] = Field(default=None, alias="isUserDefined")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ContextGroundingDataSource(BaseModel):
|
|
18
|
+
model_config = ConfigDict(
|
|
19
|
+
validate_by_name=True,
|
|
20
|
+
validate_by_alias=True,
|
|
21
|
+
use_enum_values=True,
|
|
22
|
+
arbitrary_types_allowed=True,
|
|
23
|
+
extra="allow",
|
|
24
|
+
json_encoders={datetime: lambda v: v.isoformat() if v else None},
|
|
25
|
+
)
|
|
26
|
+
id: Optional[str] = Field(default=None, alias="id")
|
|
27
|
+
folder: Optional[str] = Field(default=None, alias="folder")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ContextGroundingIndex(BaseModel):
|
|
31
|
+
model_config = ConfigDict(
|
|
32
|
+
validate_by_name=True,
|
|
33
|
+
validate_by_alias=True,
|
|
34
|
+
use_enum_values=True,
|
|
35
|
+
arbitrary_types_allowed=True,
|
|
36
|
+
extra="allow",
|
|
37
|
+
json_encoders={datetime: lambda v: v.isoformat() if v else None},
|
|
38
|
+
)
|
|
39
|
+
id: Optional[str] = Field(default=None, alias="id")
|
|
40
|
+
name: Optional[str] = Field(default=None, alias="name")
|
|
41
|
+
description: Optional[str] = Field(default=None, alias="description")
|
|
42
|
+
memory_usage: Optional[int] = Field(default=None, alias="memoryUsage")
|
|
43
|
+
disk_usage: Optional[int] = Field(default=None, alias="diskUsage")
|
|
44
|
+
data_source: Optional[ContextGroundingDataSource] = Field(
|
|
45
|
+
default=None, alias="dataSource"
|
|
46
|
+
)
|
|
47
|
+
pre_processing: Any = Field(default=None, alias="preProcessing")
|
|
48
|
+
fields: Optional[List[ContextGroundingField]] = Field(default=None, alias="fields")
|
|
49
|
+
last_ingestion_status: Optional[str] = Field(
|
|
50
|
+
default=None, alias="lastIngestionStatus"
|
|
51
|
+
)
|
|
52
|
+
last_ingested: Optional[datetime] = Field(default=None, alias="lastIngested")
|
|
53
|
+
last_queried: Optional[datetime] = Field(default=None, alias="lastQueried")
|
|
54
|
+
folder_key: Optional[str] = Field(default=None, alias="folderKey")
|
|
55
|
+
|
|
56
|
+
def in_progress_ingestion(self):
|
|
57
|
+
return (
|
|
58
|
+
self.last_ingestion_status == "Queued"
|
|
59
|
+
or self.last_ingestion_status == "In Progress"
|
|
60
|
+
)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class IngestionInProgressException(Exception):
|
|
2
|
+
"""An exception that is triggered when a search is attempted on an index that is currently undergoing ingestion."""
|
|
3
|
+
|
|
4
|
+
def __init__(self, index_name):
|
|
5
|
+
self.message = f"index {index_name} cannot be searched during ingestion"
|
|
6
|
+
super().__init__(self.message)
|
|
@@ -4,6 +4,7 @@ from .assets_service import AssetsService
|
|
|
4
4
|
from .buckets_service import BucketsService
|
|
5
5
|
from .connections_service import ConnectionsService
|
|
6
6
|
from .context_grounding_service import ContextGroundingService
|
|
7
|
+
from .folder_service import FolderService
|
|
7
8
|
from .jobs_service import JobsService
|
|
8
9
|
from .llm_gateway_service import UiPathLlmChatService, UiPathOpenAIService
|
|
9
10
|
from .processes_service import ProcessesService
|
|
@@ -21,4 +22,5 @@ __all__ = [
|
|
|
21
22
|
"JobsService",
|
|
22
23
|
"UiPathOpenAIService",
|
|
23
24
|
"UiPathLlmChatService",
|
|
25
|
+
"FolderService",
|
|
24
26
|
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any, Dict
|
|
1
|
+
from typing import Any, Dict, Optional, Union
|
|
2
2
|
|
|
3
3
|
from httpx import request
|
|
4
4
|
|
|
@@ -59,7 +59,9 @@ class BucketsService(FolderContext, BaseService):
|
|
|
59
59
|
|
|
60
60
|
def upload(
|
|
61
61
|
self,
|
|
62
|
-
|
|
62
|
+
*,
|
|
63
|
+
bucket_key: Optional[str] = None,
|
|
64
|
+
bucket_name: Optional[str] = None,
|
|
63
65
|
blob_file_path: str,
|
|
64
66
|
content_type: str,
|
|
65
67
|
source_path: str,
|
|
@@ -68,11 +70,18 @@ class BucketsService(FolderContext, BaseService):
|
|
|
68
70
|
|
|
69
71
|
Args:
|
|
70
72
|
bucket_key: The key of the bucket
|
|
73
|
+
bucket_name: The name of the bucket
|
|
71
74
|
blob_file_path: The path where the file will be stored in the bucket
|
|
72
75
|
content_type: The MIME type of the file
|
|
73
76
|
source_path: The local path of the file to upload
|
|
74
77
|
"""
|
|
75
|
-
|
|
78
|
+
if bucket_key:
|
|
79
|
+
bucket = self.retrieve_by_key(bucket_key)
|
|
80
|
+
elif bucket_name:
|
|
81
|
+
bucket = self.retrieve(bucket_name)
|
|
82
|
+
else:
|
|
83
|
+
raise ValueError("Must specify a bucket name or bucket key")
|
|
84
|
+
|
|
76
85
|
bucket_id = bucket["Id"]
|
|
77
86
|
|
|
78
87
|
endpoint = Endpoint(
|
|
@@ -99,6 +108,60 @@ class BucketsService(FolderContext, BaseService):
|
|
|
99
108
|
else:
|
|
100
109
|
request("PUT", write_uri, headers=headers, files={"file": file})
|
|
101
110
|
|
|
111
|
+
def upload_from_memory(
|
|
112
|
+
self,
|
|
113
|
+
*,
|
|
114
|
+
bucket_key: Optional[str] = None,
|
|
115
|
+
bucket_name: Optional[str] = None,
|
|
116
|
+
blob_file_path: str,
|
|
117
|
+
content_type: str,
|
|
118
|
+
content: Union[str, bytes],
|
|
119
|
+
) -> None:
|
|
120
|
+
"""Upload content from memory to a bucket.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
bucket_key: The key of the bucket
|
|
124
|
+
bucket_name: The name of the bucket
|
|
125
|
+
blob_file_path: The path where the content will be stored in the bucket
|
|
126
|
+
content_type: The MIME type of the content
|
|
127
|
+
content: The content to upload (string or bytes)
|
|
128
|
+
"""
|
|
129
|
+
if bucket_key:
|
|
130
|
+
bucket = self.retrieve_by_key(bucket_key)
|
|
131
|
+
elif bucket_name:
|
|
132
|
+
bucket = self.retrieve(bucket_name)
|
|
133
|
+
else:
|
|
134
|
+
raise ValueError("Must specify a bucket name or bucket key")
|
|
135
|
+
|
|
136
|
+
bucket_id = bucket["Id"]
|
|
137
|
+
|
|
138
|
+
endpoint = Endpoint(
|
|
139
|
+
f"/orchestrator_/odata/Buckets({bucket_id})/UiPath.Server.Configuration.OData.GetWriteUri"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
result = self.request(
|
|
143
|
+
"GET",
|
|
144
|
+
endpoint,
|
|
145
|
+
params={"path": blob_file_path, "contentType": content_type},
|
|
146
|
+
).json()
|
|
147
|
+
write_uri = result["Uri"]
|
|
148
|
+
|
|
149
|
+
headers = {
|
|
150
|
+
key: value
|
|
151
|
+
for key, value in zip(
|
|
152
|
+
result["Headers"]["Keys"], result["Headers"]["Values"]
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
# Convert string to bytes if needed
|
|
157
|
+
if isinstance(content, str):
|
|
158
|
+
content = content.encode("utf-8")
|
|
159
|
+
|
|
160
|
+
if result["RequiresAuth"]:
|
|
161
|
+
self.request("PUT", write_uri, headers=headers, content=content)
|
|
162
|
+
else:
|
|
163
|
+
request("PUT", write_uri, headers=headers, content=content)
|
|
164
|
+
|
|
102
165
|
@infer_bindings()
|
|
103
166
|
def retrieve(self, name: str) -> Any:
|
|
104
167
|
"""Retrieve bucket information by its name.
|
|
@@ -192,7 +255,7 @@ class BucketsService(FolderContext, BaseService):
|
|
|
192
255
|
def _retrieve_spec(self, name: str) -> RequestSpec:
|
|
193
256
|
return RequestSpec(
|
|
194
257
|
method="GET",
|
|
195
|
-
endpoint=Endpoint("/odata/Buckets"),
|
|
258
|
+
endpoint=Endpoint("/orchestrator_/odata/Buckets"),
|
|
196
259
|
params={"$filter": f"Name eq '{name}'", "$top": 1},
|
|
197
260
|
)
|
|
198
261
|
|
|
@@ -200,6 +263,6 @@ class BucketsService(FolderContext, BaseService):
|
|
|
200
263
|
return RequestSpec(
|
|
201
264
|
method="GET",
|
|
202
265
|
endpoint=Endpoint(
|
|
203
|
-
f"/odata/Buckets/UiPath.Server.Configuration.OData.GetByKey(identifier={key})"
|
|
266
|
+
f"/orchestrator_/odata/Buckets/UiPath.Server.Configuration.OData.GetByKey(identifier={key})"
|
|
204
267
|
),
|
|
205
268
|
)
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from typing import Any, Dict, List
|
|
2
|
+
from typing import Any, Dict, List, Optional
|
|
3
3
|
|
|
4
4
|
from pydantic import TypeAdapter
|
|
5
5
|
|
|
6
6
|
from .._config import Config
|
|
7
7
|
from .._execution_context import ExecutionContext
|
|
8
8
|
from .._folder_context import FolderContext
|
|
9
|
+
from .._models import IngestionInProgressException
|
|
9
10
|
from .._models.context_grounding import ContextGroundingQueryResponse
|
|
11
|
+
from .._models.context_grounding_index import ContextGroundingIndex
|
|
10
12
|
from .._utils import Endpoint, RequestSpec
|
|
13
|
+
from .._utils.constants import (
|
|
14
|
+
HEADER_FOLDER_KEY,
|
|
15
|
+
ORCHESTRATOR_STORAGE_BUCKET_DATA_SOURCE,
|
|
16
|
+
)
|
|
11
17
|
from ._base_service import BaseService
|
|
18
|
+
from .folder_service import FolderService
|
|
12
19
|
|
|
13
20
|
|
|
14
21
|
class ContextGroundingService(FolderContext, BaseService):
|
|
@@ -24,10 +31,16 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
24
31
|
context.
|
|
25
32
|
"""
|
|
26
33
|
|
|
27
|
-
def __init__(
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
config: Config,
|
|
37
|
+
execution_context: ExecutionContext,
|
|
38
|
+
folders_service: FolderService,
|
|
39
|
+
) -> None:
|
|
40
|
+
self._folders_service = folders_service
|
|
28
41
|
super().__init__(config=config, execution_context=execution_context)
|
|
29
42
|
|
|
30
|
-
def retrieve(self, name: str) ->
|
|
43
|
+
def retrieve(self, name: str) -> Optional[ContextGroundingIndex]:
|
|
31
44
|
"""Retrieve context grounding index information by its name.
|
|
32
45
|
|
|
33
46
|
This method fetches details about a specific context index, which can be
|
|
@@ -38,17 +51,25 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
38
51
|
name (str): The name of the context index to retrieve.
|
|
39
52
|
|
|
40
53
|
Returns:
|
|
41
|
-
|
|
54
|
+
Optional[ContextGroundingIndex]: The index information, including its configuration and metadata if found, otherwise None.
|
|
42
55
|
"""
|
|
43
56
|
spec = self._retrieve_spec(name)
|
|
44
57
|
|
|
45
|
-
|
|
58
|
+
response = self.request(
|
|
46
59
|
spec.method,
|
|
47
60
|
spec.endpoint,
|
|
48
61
|
params=spec.params,
|
|
49
62
|
).json()
|
|
63
|
+
return next(
|
|
64
|
+
(
|
|
65
|
+
ContextGroundingIndex.model_validate(item)
|
|
66
|
+
for item in response["value"]
|
|
67
|
+
if item["name"] == name
|
|
68
|
+
),
|
|
69
|
+
None,
|
|
70
|
+
)
|
|
50
71
|
|
|
51
|
-
async def retrieve_async(self, name: str) ->
|
|
72
|
+
async def retrieve_async(self, name: str) -> Optional[ContextGroundingIndex]:
|
|
52
73
|
"""Retrieve asynchronously context grounding index information by its name.
|
|
53
74
|
|
|
54
75
|
This method fetches details about a specific context index, which can be
|
|
@@ -59,19 +80,27 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
59
80
|
name (str): The name of the context index to retrieve.
|
|
60
81
|
|
|
61
82
|
Returns:
|
|
62
|
-
|
|
83
|
+
Optional[ContextGroundingIndex]: The index information, including its configuration and metadata if found, otherwise None.
|
|
63
84
|
|
|
64
85
|
"""
|
|
65
86
|
spec = self._retrieve_spec(name)
|
|
66
87
|
|
|
67
|
-
response =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
response = (
|
|
89
|
+
await self.request_async(
|
|
90
|
+
spec.method,
|
|
91
|
+
spec.endpoint,
|
|
92
|
+
params=spec.params,
|
|
93
|
+
)
|
|
94
|
+
).json()
|
|
95
|
+
return next(
|
|
96
|
+
(
|
|
97
|
+
ContextGroundingIndex.model_validate(item)
|
|
98
|
+
for item in response["value"]
|
|
99
|
+
if item["name"] == name
|
|
100
|
+
),
|
|
101
|
+
None,
|
|
71
102
|
)
|
|
72
103
|
|
|
73
|
-
return response.json()
|
|
74
|
-
|
|
75
104
|
def retrieve_by_id(self, id: str) -> Any:
|
|
76
105
|
"""Retrieve context grounding index information by its ID.
|
|
77
106
|
|
|
@@ -137,6 +166,10 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
137
166
|
List[ContextGroundingQueryResponse]: A list of search results, each containing
|
|
138
167
|
relevant contextual information and metadata.
|
|
139
168
|
"""
|
|
169
|
+
index = self.retrieve(name)
|
|
170
|
+
if index and index.in_progress_ingestion():
|
|
171
|
+
raise IngestionInProgressException(index_name=name)
|
|
172
|
+
|
|
140
173
|
spec = self._search_spec(name, query, number_of_results)
|
|
141
174
|
|
|
142
175
|
response = self.request(
|
|
@@ -171,6 +204,9 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
171
204
|
List[ContextGroundingQueryResponse]: A list of search results, each containing
|
|
172
205
|
relevant contextual information and metadata.
|
|
173
206
|
"""
|
|
207
|
+
index = self.retrieve(name)
|
|
208
|
+
if index and index.in_progress_ingestion():
|
|
209
|
+
raise IngestionInProgressException(index_name=name)
|
|
174
210
|
spec = self._search_spec(name, query, number_of_results)
|
|
175
211
|
|
|
176
212
|
response = await self.request_async(
|
|
@@ -183,13 +219,122 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
183
219
|
response.json()
|
|
184
220
|
)
|
|
185
221
|
|
|
222
|
+
def get_or_create_index(
|
|
223
|
+
self,
|
|
224
|
+
name: str,
|
|
225
|
+
*,
|
|
226
|
+
description: Optional[str] = None,
|
|
227
|
+
storage_bucket_name: str,
|
|
228
|
+
file_name_glob: Optional[str] = None,
|
|
229
|
+
storage_bucket_folder_path: Optional[str] = None,
|
|
230
|
+
) -> ContextGroundingIndex:
|
|
231
|
+
spec = self._create_spec(
|
|
232
|
+
name,
|
|
233
|
+
description,
|
|
234
|
+
storage_bucket_name,
|
|
235
|
+
file_name_glob,
|
|
236
|
+
storage_bucket_folder_path,
|
|
237
|
+
)
|
|
238
|
+
index = self.retrieve(name=name)
|
|
239
|
+
if index:
|
|
240
|
+
return index
|
|
241
|
+
|
|
242
|
+
response = self.request(
|
|
243
|
+
spec.method,
|
|
244
|
+
spec.endpoint,
|
|
245
|
+
content=spec.content,
|
|
246
|
+
headers=spec.headers,
|
|
247
|
+
).json()
|
|
248
|
+
return ContextGroundingIndex.model_validate(response)
|
|
249
|
+
|
|
250
|
+
async def get_or_create_index_async(
|
|
251
|
+
self,
|
|
252
|
+
name: str,
|
|
253
|
+
*,
|
|
254
|
+
description: Optional[str] = None,
|
|
255
|
+
storage_bucket_name: str,
|
|
256
|
+
file_name_glob: Optional[str] = None,
|
|
257
|
+
storage_bucket_folder_path: Optional[str] = None,
|
|
258
|
+
) -> ContextGroundingIndex:
|
|
259
|
+
index = await self.retrieve_async(name=name)
|
|
260
|
+
if index:
|
|
261
|
+
return index
|
|
262
|
+
|
|
263
|
+
spec = self._create_spec(
|
|
264
|
+
name,
|
|
265
|
+
description,
|
|
266
|
+
storage_bucket_name,
|
|
267
|
+
file_name_glob,
|
|
268
|
+
storage_bucket_folder_path,
|
|
269
|
+
)
|
|
270
|
+
response = (
|
|
271
|
+
await self.request_async(
|
|
272
|
+
spec.method,
|
|
273
|
+
spec.endpoint,
|
|
274
|
+
content=spec.content,
|
|
275
|
+
headers=spec.headers,
|
|
276
|
+
)
|
|
277
|
+
).json()
|
|
278
|
+
return ContextGroundingIndex.model_validate(response)
|
|
279
|
+
|
|
280
|
+
def ingest_data(self, index: ContextGroundingIndex) -> None:
|
|
281
|
+
if not index.id:
|
|
282
|
+
return
|
|
283
|
+
spec = self._ingest_spec(index.id)
|
|
284
|
+
self.request(
|
|
285
|
+
spec.method,
|
|
286
|
+
spec.endpoint,
|
|
287
|
+
headers=spec.headers,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
async def ingest_data_async(self, index: ContextGroundingIndex) -> None:
|
|
291
|
+
if not index.id:
|
|
292
|
+
return
|
|
293
|
+
spec = self._ingest_spec(index.id)
|
|
294
|
+
await self.request_async(
|
|
295
|
+
spec.method,
|
|
296
|
+
spec.endpoint,
|
|
297
|
+
headers=spec.headers,
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
def delete_index(self, index: ContextGroundingIndex) -> None:
|
|
301
|
+
if not index.id:
|
|
302
|
+
return
|
|
303
|
+
spec = self._delete_by_id_spec(index.id)
|
|
304
|
+
self.request(
|
|
305
|
+
spec.method,
|
|
306
|
+
spec.endpoint,
|
|
307
|
+
headers=spec.headers,
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
async def delete_index_async(self, index: ContextGroundingIndex) -> None:
|
|
311
|
+
if not index.id:
|
|
312
|
+
return
|
|
313
|
+
spec = self._delete_by_id_spec(index.id)
|
|
314
|
+
await self.request_async(
|
|
315
|
+
spec.method,
|
|
316
|
+
spec.endpoint,
|
|
317
|
+
headers=spec.headers,
|
|
318
|
+
)
|
|
319
|
+
|
|
186
320
|
@property
|
|
187
321
|
def custom_headers(self) -> Dict[str, str]:
|
|
188
|
-
|
|
189
|
-
|
|
322
|
+
self._folder_key = self._folder_key or (
|
|
323
|
+
self._folders_service.retrieve_key_by_folder_path(self._folder_path)
|
|
324
|
+
if self._folder_path
|
|
325
|
+
else None
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
if self._folder_key is None:
|
|
329
|
+
raise ValueError(f"Folder key is not set ({HEADER_FOLDER_KEY})")
|
|
190
330
|
|
|
191
331
|
return self.folder_headers
|
|
192
332
|
|
|
333
|
+
def _ingest_spec(self, key: str) -> RequestSpec:
|
|
334
|
+
return RequestSpec(
|
|
335
|
+
method="POST", endpoint=Endpoint(f"/ecs_/v2/indexes/{key}/ingest")
|
|
336
|
+
)
|
|
337
|
+
|
|
193
338
|
def _retrieve_spec(self, name: str) -> RequestSpec:
|
|
194
339
|
return RequestSpec(
|
|
195
340
|
method="GET",
|
|
@@ -197,12 +342,51 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
197
342
|
params={"$filter": f"Name eq '{name}'"},
|
|
198
343
|
)
|
|
199
344
|
|
|
345
|
+
def _create_spec(
|
|
346
|
+
self,
|
|
347
|
+
name: str,
|
|
348
|
+
description: Optional[str],
|
|
349
|
+
storage_bucket_name: Optional[str],
|
|
350
|
+
file_name_glob: Optional[str],
|
|
351
|
+
storage_bucket_folder_path: Optional[str],
|
|
352
|
+
) -> RequestSpec:
|
|
353
|
+
storage_bucket_folder_path = (
|
|
354
|
+
storage_bucket_folder_path
|
|
355
|
+
if storage_bucket_folder_path
|
|
356
|
+
else self._folder_path
|
|
357
|
+
)
|
|
358
|
+
return RequestSpec(
|
|
359
|
+
method="POST",
|
|
360
|
+
endpoint=Endpoint("/ecs_/v2/indexes/create"),
|
|
361
|
+
content=json.dumps(
|
|
362
|
+
{
|
|
363
|
+
"name": name,
|
|
364
|
+
"description": description,
|
|
365
|
+
"dataSource": {
|
|
366
|
+
"@odata.type": ORCHESTRATOR_STORAGE_BUCKET_DATA_SOURCE,
|
|
367
|
+
"folder": storage_bucket_folder_path,
|
|
368
|
+
"bucketName": storage_bucket_name,
|
|
369
|
+
"fileNameGlob": file_name_glob
|
|
370
|
+
if file_name_glob is not None
|
|
371
|
+
else "*",
|
|
372
|
+
"directoryPath": "/",
|
|
373
|
+
},
|
|
374
|
+
}
|
|
375
|
+
),
|
|
376
|
+
)
|
|
377
|
+
|
|
200
378
|
def _retrieve_by_id_spec(self, id: str) -> RequestSpec:
|
|
201
379
|
return RequestSpec(
|
|
202
380
|
method="GET",
|
|
203
381
|
endpoint=Endpoint(f"/ecs_/v2/indexes/{id}"),
|
|
204
382
|
)
|
|
205
383
|
|
|
384
|
+
def _delete_by_id_spec(self, id: str) -> RequestSpec:
|
|
385
|
+
return RequestSpec(
|
|
386
|
+
method="DELETE",
|
|
387
|
+
endpoint=Endpoint(f"/ecs_/v2/indexes/{id}"),
|
|
388
|
+
)
|
|
389
|
+
|
|
206
390
|
def _search_spec(
|
|
207
391
|
self, name: str, query: str, number_of_results: int = 10
|
|
208
392
|
) -> RequestSpec:
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from .._config import Config
|
|
4
|
+
from .._execution_context import ExecutionContext
|
|
5
|
+
from .._utils import Endpoint, RequestSpec
|
|
6
|
+
from ._base_service import BaseService
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _retrieve_spec(folder_path: str) -> RequestSpec:
|
|
10
|
+
folder_name = folder_path.split("/")[-1]
|
|
11
|
+
return RequestSpec(
|
|
12
|
+
method="GET",
|
|
13
|
+
endpoint=Endpoint(
|
|
14
|
+
"orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser"
|
|
15
|
+
),
|
|
16
|
+
params={
|
|
17
|
+
"searchText": folder_name,
|
|
18
|
+
"take": 1,
|
|
19
|
+
},
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class FolderService(BaseService):
|
|
24
|
+
"""Service for managing UiPath Folders.
|
|
25
|
+
|
|
26
|
+
A folder represents a single area for data organization
|
|
27
|
+
and access control - it is created when you need to categorize, manage, and enforce authorization rules for a group
|
|
28
|
+
of UiPath resources (i.e. processes, assets, connections, storage buckets etc.) or other folders
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, config: Config, execution_context: ExecutionContext) -> None:
|
|
32
|
+
super().__init__(config=config, execution_context=execution_context)
|
|
33
|
+
|
|
34
|
+
def retrieve_key_by_folder_path(self, folder_path: str) -> Optional[str]:
|
|
35
|
+
spec = _retrieve_spec(folder_path)
|
|
36
|
+
response = self.request(
|
|
37
|
+
spec.method,
|
|
38
|
+
url=spec.endpoint,
|
|
39
|
+
params=spec.params,
|
|
40
|
+
).json()
|
|
41
|
+
|
|
42
|
+
return next(
|
|
43
|
+
(
|
|
44
|
+
item["Key"]
|
|
45
|
+
for item in response["PageItems"]
|
|
46
|
+
if item["FullyQualifiedName"] == folder_path
|
|
47
|
+
),
|
|
48
|
+
None,
|
|
49
|
+
)
|
|
@@ -12,6 +12,7 @@ from ._services import (
|
|
|
12
12
|
BucketsService,
|
|
13
13
|
ConnectionsService,
|
|
14
14
|
ContextGroundingService,
|
|
15
|
+
FolderService,
|
|
15
16
|
JobsService,
|
|
16
17
|
ProcessesService,
|
|
17
18
|
QueuesService,
|
|
@@ -45,6 +46,7 @@ class UiPath:
|
|
|
45
46
|
base_url=base_url_value, # type: ignore
|
|
46
47
|
secret=secret_value, # type: ignore
|
|
47
48
|
)
|
|
49
|
+
self._folders_service: Optional[FolderService] = None
|
|
48
50
|
|
|
49
51
|
setup_logging(debug)
|
|
50
52
|
self._execution_context = ExecutionContext()
|
|
@@ -75,7 +77,11 @@ class UiPath:
|
|
|
75
77
|
|
|
76
78
|
@property
|
|
77
79
|
def context_grounding(self) -> ContextGroundingService:
|
|
78
|
-
|
|
80
|
+
if not self._folders_service:
|
|
81
|
+
self._folders_service = FolderService(self._config, self._execution_context)
|
|
82
|
+
return ContextGroundingService(
|
|
83
|
+
self._config, self._execution_context, self._folders_service
|
|
84
|
+
)
|
|
79
85
|
|
|
80
86
|
@property
|
|
81
87
|
def queues(self) -> QueuesService:
|
|
@@ -84,3 +90,9 @@ class UiPath:
|
|
|
84
90
|
@property
|
|
85
91
|
def jobs(self) -> JobsService:
|
|
86
92
|
return JobsService(self._config, self._execution_context)
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def folders(self) -> FolderService:
|
|
96
|
+
if not self._folders_service:
|
|
97
|
+
self._folders_service = FolderService(self._config, self._execution_context)
|
|
98
|
+
return self._folders_service
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|