uipath 2.1.38__py3-none-any.whl → 2.1.40__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.
@@ -421,6 +421,8 @@ class SwFileHandler:
421
421
  "bindings", {"version": "2.0", "resources": []}
422
422
  ),
423
423
  "settings": {},
424
+ # TODO: remove this after validation check gets removed on SW side
425
+ "entryPoints": [{}],
424
426
  }
425
427
 
426
428
  existing = root_files.get("agent.json")
@@ -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
- return _try_convert_to_json_format(job.output_arguments)
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:
@@ -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__(self, config: Config, execution_context: ExecutionContext) -> None:
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
- input_arguments=input_arguments,
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
- input_arguments=input_arguments,
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
- input_arguments: Optional[Dict[str, Any]] = None,
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
- return AttachmentsService(self._config, self._execution_context)
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.38
3
+ Version: 2.1.40
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=vYSrugpWOufwXln7y4rn6SvoDWwZq2KMX5prAvCyHHM,4087
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
@@ -56,10 +56,10 @@ uipath/_cli/_evals/_evaluators/_trajectory_evaluator.py,sha256=dnogQTOskpI4_cNF0
56
56
  uipath/_cli/_evals/_models/__init__.py,sha256=Ewjp3u2YeTH2MmzY9LWf7EIbAoIf_nW9fMYbj7pGlPs,420
57
57
  uipath/_cli/_evals/_models/_evaluation_set.py,sha256=tVHykSget-G3sOCs9bSchMYUTpFqzXVlYYbY8L9SI0c,1518
58
58
  uipath/_cli/_evals/_models/_evaluators.py,sha256=l57NEVyYmzSKuoIXuGkE94Br01hAMg35fiS2MlTkaQM,2115
59
- uipath/_cli/_push/sw_file_handler.py,sha256=NTXITAs0qzmQyFnnSbq8HW16TGxzkqtgs4tWS1H5A2U,18090
59
+ uipath/_cli/_push/sw_file_handler.py,sha256=AX4TKM-q6CNGw3JyBW02M8ktPZuFMcAU9LN3Ii0Q2QI,18202
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=aexwe0dIXvh6SlVS1jVnO_aGZc6e3gLsmGkCyha5AHo,11300
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=CnDd7BM4AMqcMIR1qqu5ohhxf9m0AF4dnGoF4EX38kw,30872
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=Pk6paw7e_a-WvVcfKDLuyj1p--pvNRTXwZNYIwDdYzo,5726
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=f9L6_kg_VP0dAYvdcz1DWEWzy4NZPdlpHREod0uNK1E,3099
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.38.dist-info/METADATA,sha256=n4_EH5ABqSOm4r2JbudngTSg8vDV7T6E6Bm-mqFu0Bc,6482
143
- uipath-2.1.38.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
144
- uipath-2.1.38.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
145
- uipath-2.1.38.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
146
- uipath-2.1.38.dist-info/RECORD,,
142
+ uipath-2.1.40.dist-info/METADATA,sha256=Qzmiy04dDbd6AhRGQUWrk0R6qSTBTxIJtjY5kTB6V64,6482
143
+ uipath-2.1.40.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
144
+ uipath-2.1.40.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
145
+ uipath-2.1.40.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
146
+ uipath-2.1.40.dist-info/RECORD,,