uipath 2.1.38__py3-none-any.whl → 2.1.39__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.
- uipath/_cli/_runtime/_hitl.py +2 -1
- uipath/_services/jobs_service.py +48 -0
- uipath/_services/processes_service.py +90 -14
- uipath/_uipath.py +7 -2
- uipath/models/job.py +2 -0
- {uipath-2.1.38.dist-info → uipath-2.1.39.dist-info}/METADATA +1 -1
- {uipath-2.1.38.dist-info → uipath-2.1.39.dist-info}/RECORD +10 -10
- {uipath-2.1.38.dist-info → uipath-2.1.39.dist-info}/WHEEL +0 -0
- {uipath-2.1.38.dist-info → uipath-2.1.39.dist-info}/entry_points.txt +0 -0
- {uipath-2.1.38.dist-info → uipath-2.1.39.dist-info}/licenses/LICENSE +0 -0
uipath/_cli/_runtime/_hitl.py
CHANGED
@@ -92,7 +92,8 @@ class HitlReader:
|
|
92
92
|
_try_convert_to_json_format(str(job.job_error or job.info))
|
93
93
|
or "Job error unavailable.",
|
94
94
|
)
|
95
|
-
|
95
|
+
output_data = await uipath.jobs.extract_output_async(job)
|
96
|
+
return _try_convert_to_json_format(output_data)
|
96
97
|
|
97
98
|
case UiPathResumeTriggerType.API:
|
98
99
|
if resume_trigger.api_resume and resume_trigger.api_resume.inbox_id:
|
uipath/_services/jobs_service.py
CHANGED
@@ -351,6 +351,54 @@ class JobsService(FolderContext, BaseService):
|
|
351
351
|
},
|
352
352
|
)
|
353
353
|
|
354
|
+
def extract_output(self, job: Job) -> Optional[str]:
|
355
|
+
"""Get the actual output data, downloading from attachment if necessary.
|
356
|
+
|
357
|
+
Args:
|
358
|
+
job: The job instance to fetch output data from.
|
359
|
+
|
360
|
+
Returns:
|
361
|
+
Parsed output arguments as dictionary, or None if no output
|
362
|
+
"""
|
363
|
+
if job.output_file:
|
364
|
+
# Large output stored as attachment
|
365
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
366
|
+
temp_path = Path(temp_dir) / f"output_{job.output_file}"
|
367
|
+
self._attachments_service.download(
|
368
|
+
key=uuid.UUID(job.output_file), destination_path=temp_path
|
369
|
+
)
|
370
|
+
with open(temp_path, "r", encoding="utf-8") as f:
|
371
|
+
return f.read()
|
372
|
+
elif job.output_arguments:
|
373
|
+
# Small output stored inline
|
374
|
+
return job.output_arguments
|
375
|
+
else:
|
376
|
+
return None
|
377
|
+
|
378
|
+
async def extract_output_async(self, job: Job) -> Optional[str]:
|
379
|
+
"""Asynchronously fetch the actual output data, downloading from attachment if necessary.
|
380
|
+
|
381
|
+
Args:
|
382
|
+
job: The job instance to fetch output data from.
|
383
|
+
|
384
|
+
Returns:
|
385
|
+
Parsed output arguments as dictionary, or None if no output
|
386
|
+
"""
|
387
|
+
if job.output_file:
|
388
|
+
# Large output stored as attachment
|
389
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
390
|
+
temp_path = Path(temp_dir) / f"output_{job.output_file}"
|
391
|
+
await self._attachments_service.download_async(
|
392
|
+
key=uuid.UUID(job.output_file), destination_path=temp_path
|
393
|
+
)
|
394
|
+
with open(temp_path, "r", encoding="utf-8") as f:
|
395
|
+
return f.read()
|
396
|
+
elif job.output_arguments:
|
397
|
+
# Small output stored inline
|
398
|
+
return job.output_arguments
|
399
|
+
else:
|
400
|
+
return None
|
401
|
+
|
354
402
|
def _resume_spec(
|
355
403
|
self,
|
356
404
|
*,
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import json
|
2
2
|
import os
|
3
|
+
import uuid
|
3
4
|
from typing import Any, Dict, Optional
|
4
5
|
|
5
6
|
from .._config import Config
|
@@ -9,6 +10,7 @@ from .._utils import Endpoint, RequestSpec, header_folder, infer_bindings
|
|
9
10
|
from .._utils.constants import ENV_JOB_ID, HEADER_JOB_KEY
|
10
11
|
from ..models.job import Job
|
11
12
|
from ..tracing._traced import traced
|
13
|
+
from . import AttachmentsService
|
12
14
|
from ._base_service import BaseService
|
13
15
|
|
14
16
|
|
@@ -20,7 +22,13 @@ class ProcessesService(FolderContext, BaseService):
|
|
20
22
|
specific business tasks.
|
21
23
|
"""
|
22
24
|
|
23
|
-
def __init__(
|
25
|
+
def __init__(
|
26
|
+
self,
|
27
|
+
config: Config,
|
28
|
+
execution_context: ExecutionContext,
|
29
|
+
attachment_service: AttachmentsService,
|
30
|
+
) -> None:
|
31
|
+
self._attachments_service = attachment_service
|
24
32
|
super().__init__(config=config, execution_context=execution_context)
|
25
33
|
|
26
34
|
@traced(name="processes_invoke", run_type="uipath")
|
@@ -65,9 +73,14 @@ class ProcessesService(FolderContext, BaseService):
|
|
65
73
|
client.processes.invoke(name="MyProcess", folder_path="my-folder-key")
|
66
74
|
```
|
67
75
|
"""
|
76
|
+
input_data = self._handle_input_arguments(
|
77
|
+
input_arguments=input_arguments,
|
78
|
+
folder_key=folder_key,
|
79
|
+
folder_path=folder_path,
|
80
|
+
)
|
68
81
|
spec = self._invoke_spec(
|
69
82
|
name,
|
70
|
-
|
83
|
+
input_data=input_data,
|
71
84
|
folder_key=folder_key,
|
72
85
|
folder_path=folder_path,
|
73
86
|
)
|
@@ -118,9 +131,14 @@ class ProcessesService(FolderContext, BaseService):
|
|
118
131
|
asyncio.run(main())
|
119
132
|
```
|
120
133
|
"""
|
134
|
+
input_data = await self._handle_input_arguments_async(
|
135
|
+
input_arguments=input_arguments,
|
136
|
+
folder_key=folder_key,
|
137
|
+
folder_path=folder_path,
|
138
|
+
)
|
121
139
|
spec = self._invoke_spec(
|
122
140
|
name,
|
123
|
-
|
141
|
+
input_data=input_data,
|
124
142
|
folder_key=folder_key,
|
125
143
|
folder_path=folder_path,
|
126
144
|
)
|
@@ -138,29 +156,87 @@ class ProcessesService(FolderContext, BaseService):
|
|
138
156
|
def custom_headers(self) -> Dict[str, str]:
|
139
157
|
return self.folder_headers
|
140
158
|
|
159
|
+
def _handle_input_arguments(
|
160
|
+
self,
|
161
|
+
input_arguments: Optional[Dict[str, Any]] = None,
|
162
|
+
*,
|
163
|
+
folder_key: Optional[str] = None,
|
164
|
+
folder_path: Optional[str] = None,
|
165
|
+
) -> Dict[str, str]:
|
166
|
+
"""Handle input arguments, storing as attachment if they exceed size limit.
|
167
|
+
|
168
|
+
Args:
|
169
|
+
input_arguments: The input arguments to process
|
170
|
+
folder_key: The folder key for attachment storage
|
171
|
+
folder_path: The folder path for attachment storage
|
172
|
+
|
173
|
+
Returns:
|
174
|
+
Dict containing either "InputArguments" or "InputFile" key
|
175
|
+
"""
|
176
|
+
if not input_arguments:
|
177
|
+
return {"InputArguments": json.dumps({})}
|
178
|
+
|
179
|
+
# If payload exceeds limit, store as attachment
|
180
|
+
payload_json = json.dumps(input_arguments)
|
181
|
+
if len(payload_json) > 10000: # 10k char limit
|
182
|
+
attachment_id = self._attachments_service.upload(
|
183
|
+
name=f"{uuid.uuid4()}.json",
|
184
|
+
content=payload_json,
|
185
|
+
folder_key=folder_key,
|
186
|
+
folder_path=folder_path,
|
187
|
+
)
|
188
|
+
return {"InputFile": str(attachment_id)}
|
189
|
+
else:
|
190
|
+
return {"InputArguments": payload_json}
|
191
|
+
|
192
|
+
async def _handle_input_arguments_async(
|
193
|
+
self,
|
194
|
+
input_arguments: Optional[Dict[str, Any]] = None,
|
195
|
+
*,
|
196
|
+
folder_key: Optional[str] = None,
|
197
|
+
folder_path: Optional[str] = None,
|
198
|
+
) -> Dict[str, str]:
|
199
|
+
"""Handle input arguments, storing as attachment if they exceed size limit.
|
200
|
+
|
201
|
+
Args:
|
202
|
+
input_arguments: The input arguments to process
|
203
|
+
folder_key: The folder key for attachment storage
|
204
|
+
folder_path: The folder path for attachment storage
|
205
|
+
|
206
|
+
Returns:
|
207
|
+
Dict containing either "InputArguments" or "InputFile" key
|
208
|
+
"""
|
209
|
+
if not input_arguments:
|
210
|
+
return {"InputArguments": json.dumps({})}
|
211
|
+
|
212
|
+
# If payload exceeds limit, store as attachment
|
213
|
+
payload_json = json.dumps(input_arguments)
|
214
|
+
if len(payload_json) > 10000: # 10k char limit
|
215
|
+
attachment_id = await self._attachments_service.upload_async(
|
216
|
+
name=f"{uuid.uuid4()}.json",
|
217
|
+
content=payload_json,
|
218
|
+
folder_key=folder_key,
|
219
|
+
folder_path=folder_path,
|
220
|
+
)
|
221
|
+
return {"InputFile": str(attachment_id)}
|
222
|
+
else:
|
223
|
+
return {"InputArguments": payload_json}
|
224
|
+
|
141
225
|
def _invoke_spec(
|
142
226
|
self,
|
143
227
|
name: str,
|
144
|
-
|
228
|
+
input_data: Optional[Dict[str, Any]] = None,
|
145
229
|
*,
|
146
230
|
folder_key: Optional[str] = None,
|
147
231
|
folder_path: Optional[str] = None,
|
148
232
|
) -> RequestSpec:
|
233
|
+
input_dict = {"startInfo": {"ReleaseName": name, **(input_data or {})}}
|
149
234
|
request_scope = RequestSpec(
|
150
235
|
method="POST",
|
151
236
|
endpoint=Endpoint(
|
152
237
|
"/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"
|
153
238
|
),
|
154
|
-
content=str(
|
155
|
-
{
|
156
|
-
"startInfo": {
|
157
|
-
"ReleaseName": name,
|
158
|
-
"InputArguments": json.dumps(input_arguments)
|
159
|
-
if input_arguments
|
160
|
-
else "{}",
|
161
|
-
}
|
162
|
-
}
|
163
|
-
),
|
239
|
+
content=str(input_dict),
|
164
240
|
headers={
|
165
241
|
**header_folder(folder_key, folder_path),
|
166
242
|
},
|
uipath/_uipath.py
CHANGED
@@ -57,6 +57,7 @@ class UiPath:
|
|
57
57
|
raise SecretMissingError() from e
|
58
58
|
self._folders_service: Optional[FolderService] = None
|
59
59
|
self._buckets_service: Optional[BucketsService] = None
|
60
|
+
self._attachments_service: Optional[AttachmentsService] = None
|
60
61
|
|
61
62
|
setup_logging(debug)
|
62
63
|
self._execution_context = ExecutionContext()
|
@@ -71,11 +72,15 @@ class UiPath:
|
|
71
72
|
|
72
73
|
@property
|
73
74
|
def attachments(self) -> AttachmentsService:
|
74
|
-
|
75
|
+
if not self._attachments_service:
|
76
|
+
self._attachments_service = AttachmentsService(
|
77
|
+
self._config, self._execution_context
|
78
|
+
)
|
79
|
+
return self._attachments_service
|
75
80
|
|
76
81
|
@property
|
77
82
|
def processes(self) -> ProcessesService:
|
78
|
-
return ProcessesService(self._config, self._execution_context)
|
83
|
+
return ProcessesService(self._config, self._execution_context, self.attachments)
|
79
84
|
|
80
85
|
@property
|
81
86
|
def actions(self) -> ActionsService:
|
uipath/models/job.py
CHANGED
@@ -58,7 +58,9 @@ class Job(BaseModel):
|
|
58
58
|
deleter_user_id: Optional[int] = Field(default=None, alias="DeleterUserId")
|
59
59
|
is_deleted: Optional[bool] = Field(default=None, alias="IsDeleted")
|
60
60
|
input_arguments: Optional[str] = Field(default=None, alias="InputArguments")
|
61
|
+
input_file: Optional[str] = Field(default=None, alias="InputFile")
|
61
62
|
output_arguments: Optional[str] = Field(default=None, alias="OutputArguments")
|
63
|
+
output_file: Optional[str] = Field(default=None, alias="OutputFile")
|
62
64
|
host_machine_name: Optional[str] = Field(default=None, alias="HostMachineName")
|
63
65
|
has_errors: Optional[bool] = Field(default=None, alias="HasErrors")
|
64
66
|
has_warnings: Optional[bool] = Field(default=None, alias="HasWarnings")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: uipath
|
3
|
-
Version: 2.1.
|
3
|
+
Version: 2.1.39
|
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
|
@@ -2,7 +2,7 @@ uipath/__init__.py,sha256=IaeKItOOQXMa95avueJ3dAq-XcRHyZVNjcCGwlSB000,634
|
|
2
2
|
uipath/_config.py,sha256=pi3qxPzDTxMEstj_XkGOgKJqD6RTHHv7vYv8sS_-d5Q,92
|
3
3
|
uipath/_execution_context.py,sha256=Qo8VMUFgtiL-40KsZrvul5bGv1CRERle_fCw1ORCggY,2374
|
4
4
|
uipath/_folder_context.py,sha256=D-bgxdwpwJP4b_QdVKcPODYh15kMDrOar2xNonmMSm4,1861
|
5
|
-
uipath/_uipath.py,sha256=
|
5
|
+
uipath/_uipath.py,sha256=lDsF2rBurqxm24DlRan25z9SU9t9b2RkAGvoI645QSw,4314
|
6
6
|
uipath/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
7
|
uipath/_cli/README.md,sha256=GLtCfbeIKZKNnGTCsfSVqRQ27V1btT1i2bSAyW_xZl4,474
|
8
8
|
uipath/_cli/__init__.py,sha256=kf4GINkunFGMZkTk2Z4f1Q3-OsxpNnV6u_9BsBt1i0E,2229
|
@@ -59,7 +59,7 @@ uipath/_cli/_evals/_models/_evaluators.py,sha256=l57NEVyYmzSKuoIXuGkE94Br01hAMg3
|
|
59
59
|
uipath/_cli/_push/sw_file_handler.py,sha256=NTXITAs0qzmQyFnnSbq8HW16TGxzkqtgs4tWS1H5A2U,18090
|
60
60
|
uipath/_cli/_runtime/_contracts.py,sha256=X8lev5v4XN2sOIwKWE7VXpFgfNhQjh9UGGbgogo1llE,21246
|
61
61
|
uipath/_cli/_runtime/_escalation.py,sha256=x3vI98qsfRA-fL_tNkRVTFXioM5Gv2w0GFcXJJ5eQtg,7981
|
62
|
-
uipath/_cli/_runtime/_hitl.py,sha256=
|
62
|
+
uipath/_cli/_runtime/_hitl.py,sha256=VKbM021nVg1HEDnTfucSLJ0LsDn83CKyUtVzofS2qTU,11369
|
63
63
|
uipath/_cli/_runtime/_logging.py,sha256=MGklGKPjYKjs7J5Jy9eplA9zCDsdtEbkZdCbTwgut_4,8311
|
64
64
|
uipath/_cli/_runtime/_runtime.py,sha256=TXtXzscRPLdYJURH0Y-7sXsigC-2k_LttBOz7EUfWUQ,11449
|
65
65
|
uipath/_cli/_templates/.psmdcp.template,sha256=C7pBJPt98ovEljcBvGtEUGoWjjQhu9jls1bpYjeLOKA,611
|
@@ -89,9 +89,9 @@ uipath/_services/buckets_service.py,sha256=5s8tuivd7GUZYj774DDUYTa0axxlUuesc4EBY
|
|
89
89
|
uipath/_services/connections_service.py,sha256=Rf-DCm43tsDM6Cfp41iwGR4gUk_YCdobGcmbSoKvQ6E,7480
|
90
90
|
uipath/_services/context_grounding_service.py,sha256=EBf7lIIYz_s1ubf_07OAZXQHjS8kpZ2vqxo4mI3VL-A,25009
|
91
91
|
uipath/_services/folder_service.py,sha256=9JqgjKhWD-G_KUnfUTP2BADxL6OK9QNZsBsWZHAULdE,2749
|
92
|
-
uipath/_services/jobs_service.py,sha256=
|
92
|
+
uipath/_services/jobs_service.py,sha256=UwsY0Cir7Yd5_mTeH0uHLmcmQZpdbT8KNx3z3F0cHZA,32775
|
93
93
|
uipath/_services/llm_gateway_service.py,sha256=oZR--75V8ULdLjVC7lo-lJ5786J_qfXUDe0R9iWNAKs,24306
|
94
|
-
uipath/_services/processes_service.py,sha256=
|
94
|
+
uipath/_services/processes_service.py,sha256=y2LWLIpvWnmcdtKgXCA7q0a5WPD4mBeitTICHYTQng0,8505
|
95
95
|
uipath/_services/queues_service.py,sha256=VaG3dWL2QK6AJBOLoW2NQTpkPfZjsqsYPl9-kfXPFzA,13534
|
96
96
|
uipath/_utils/__init__.py,sha256=VdcpnENJIa0R6Y26NoxY64-wUVyvb4pKfTh1wXDQeMk,526
|
97
97
|
uipath/_utils/_endpoint.py,sha256=yYHwqbQuJIevpaTkdfYJS9CrtlFeEyfb5JQK5osTCog,2489
|
@@ -126,7 +126,7 @@ uipath/models/context_grounding_index.py,sha256=0ADlH8fC10qIbakgwU89pRVawzJ36TiS
|
|
126
126
|
uipath/models/errors.py,sha256=gPyU4sKYn57v03aOVqm97mnU9Do2e7bwMQwiSQVp9qc,461
|
127
127
|
uipath/models/exceptions.py,sha256=F0ITAhJsl6Agvmnv4nxvgY5oC_lrYIlxWTLs0yx859M,1636
|
128
128
|
uipath/models/interrupt_models.py,sha256=UzuVTMVesI204YQ4qFQFaN-gN3kksddkrujofcaC7zQ,881
|
129
|
-
uipath/models/job.py,sha256=
|
129
|
+
uipath/models/job.py,sha256=wH6Nw01NPEGn_pkQFSPID74Oabv0u48P6KW6laO4FoU,3243
|
130
130
|
uipath/models/llm_gateway.py,sha256=rUIus7BrUuuRriXqSJUE9FnjOyQ7pYpaX6hWEYvA6AA,1923
|
131
131
|
uipath/models/processes.py,sha256=Atvfrt6X4TYST3iA62jpS_Uxc3hg6uah11p-RaKZ6dk,2029
|
132
132
|
uipath/models/queues.py,sha256=N_s0GKucbyjh0RnO8SxPk6wlRgvq8KIIYsfaoIY46tM,6446
|
@@ -139,8 +139,8 @@ uipath/tracing/_traced.py,sha256=qeVDrds2OUnpdUIA0RhtF0kg2dlAZhyC1RRkI-qivTM,185
|
|
139
139
|
uipath/tracing/_utils.py,sha256=wJRELaPu69iY0AhV432Dk5QYf_N_ViRU4kAUG1BI1ew,10384
|
140
140
|
uipath/utils/__init__.py,sha256=VD-KXFpF_oWexFg6zyiWMkxl2HM4hYJMIUDZ1UEtGx0,105
|
141
141
|
uipath/utils/_endpoints_manager.py,sha256=iRTl5Q0XAm_YgcnMcJOXtj-8052sr6jpWuPNz6CgT0Q,8408
|
142
|
-
uipath-2.1.
|
143
|
-
uipath-2.1.
|
144
|
-
uipath-2.1.
|
145
|
-
uipath-2.1.
|
146
|
-
uipath-2.1.
|
142
|
+
uipath-2.1.39.dist-info/METADATA,sha256=kh00j6W3lA495EfwQDkDDt25HpFcaYdLrrB69VGc99g,6482
|
143
|
+
uipath-2.1.39.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
144
|
+
uipath-2.1.39.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
|
145
|
+
uipath-2.1.39.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
|
146
|
+
uipath-2.1.39.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|