uipath 2.1.73__py3-none-any.whl → 2.1.74__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.
@@ -50,6 +50,16 @@ class ExecutionContextFilter(logging.Filter):
50
50
  return False
51
51
 
52
52
 
53
+ class MasterExecutionFilter(logging.Filter):
54
+ """Filter for master handler that blocks logs from any child execution."""
55
+
56
+ def filter(self, record: logging.LogRecord) -> bool:
57
+ """Block logs that belong to a child execution context."""
58
+ ctx_execution_id = current_execution_id.get()
59
+ # Block if there's an active child execution context
60
+ return ctx_execution_id is None
61
+
62
+
53
63
  class LogsInterceptor:
54
64
  """Intercepts all logging and stdout/stderr, routing to either persistent log files or stdout based on whether it's running as a job or not."""
55
65
 
@@ -93,7 +103,9 @@ class LogsInterceptor:
93
103
  self.original_stderr = cast(TextIO, sys.stderr)
94
104
 
95
105
  self.log_handler: Union[
96
- PersistentLogsHandler, logging.StreamHandler[TextIO], logging.Handler
106
+ PersistentLogsHandler,
107
+ logging.StreamHandler[TextIO],
108
+ logging.Handler,
97
109
  ]
98
110
 
99
111
  if log_handler:
@@ -116,9 +128,14 @@ class LogsInterceptor:
116
128
  self.log_handler.setLevel(self.numeric_min_level)
117
129
 
118
130
  # Add execution context filter if execution_id provided
131
+ self.execution_filter: Optional[logging.Filter] = None
119
132
  if execution_id:
120
133
  self.execution_filter = ExecutionContextFilter(execution_id)
121
134
  self.log_handler.addFilter(self.execution_filter)
135
+ else:
136
+ # Master execution: filter out child execution logs
137
+ self.execution_filter = MasterExecutionFilter()
138
+ self.log_handler.addFilter(self.execution_filter)
122
139
 
123
140
  self.logger = logging.getLogger("runtime")
124
141
  self.patched_loggers: set[str] = set()
@@ -146,17 +163,23 @@ class LogsInterceptor:
146
163
  self.root_logger.setLevel(self.numeric_min_level)
147
164
 
148
165
  if self.execution_id:
149
- # Parallel execution mode: add our handler without removing others
166
+ # Child execution mode: add our handler without removing others
150
167
  if self.log_handler not in self.root_logger.handlers:
151
168
  self.root_logger.addHandler(self.log_handler)
152
169
 
153
- # Set up propagation for all existing loggers
170
+ # Keep propagation enabled so logs flow through filters
171
+ # Our ExecutionContextFilter will ensure only our logs get through our handler
154
172
  for logger_name in logging.root.manager.loggerDict:
155
173
  logger = logging.getLogger(logger_name)
156
- # Keep propagation enabled so logs flow to all handlers
174
+ # Keep propagation enabled for filtering to work
175
+ # logger.propagate remains True (default)
157
176
  self.patched_loggers.add(logger_name)
177
+
178
+ # Child executions should redirect stdout/stderr to their own handler
179
+ # This ensures print statements are captured per execution
180
+ self._redirect_stdout_stderr()
158
181
  else:
159
- # Single execution mode: remove all handlers and add only ours
182
+ # Master execution mode: remove all handlers and add only ours
160
183
  self._clean_all_handlers(self.root_logger)
161
184
 
162
185
  # Set up propagation for all existing loggers
@@ -166,8 +189,8 @@ class LogsInterceptor:
166
189
  self._clean_all_handlers(logger)
167
190
  self.patched_loggers.add(logger_name)
168
191
 
169
- # Set up stdout/stderr redirection
170
- self._redirect_stdout_stderr()
192
+ # Master redirects stdout/stderr
193
+ self._redirect_stdout_stderr()
171
194
 
172
195
  def _redirect_stdout_stderr(self) -> None:
173
196
  """Redirect stdout and stderr to the logging system."""
@@ -218,15 +241,20 @@ class LogsInterceptor:
218
241
  stdout_logger = logging.getLogger("stdout")
219
242
  stderr_logger = logging.getLogger("stderr")
220
243
 
221
- stdout_logger.propagate = False
222
- stderr_logger.propagate = False
223
-
224
244
  if self.execution_id:
245
+ # Child execution: add our handler to stdout/stderr loggers
246
+ stdout_logger.propagate = False
247
+ stderr_logger.propagate = False
248
+
225
249
  if self.log_handler not in stdout_logger.handlers:
226
250
  stdout_logger.addHandler(self.log_handler)
227
251
  if self.log_handler not in stderr_logger.handlers:
228
252
  stderr_logger.addHandler(self.log_handler)
229
253
  else:
254
+ # Master execution: clean and set up handlers
255
+ stdout_logger.propagate = False
256
+ stderr_logger.propagate = False
257
+
230
258
  self._clean_all_handlers(stdout_logger)
231
259
  self._clean_all_handlers(stderr_logger)
232
260
 
@@ -249,23 +277,22 @@ class LogsInterceptor:
249
277
  logging.disable(self.original_disable_level)
250
278
 
251
279
  # Remove our handler and filter
252
- if self.execution_id:
253
- if hasattr(self, "execution_filter"):
254
- self.log_handler.removeFilter(self.execution_filter)
255
- if self.log_handler in self.root_logger.handlers:
256
- self.root_logger.removeHandler(self.log_handler)
257
-
258
- # Remove from stdout/stderr loggers too
259
- stdout_logger = logging.getLogger("stdout")
260
- stderr_logger = logging.getLogger("stderr")
261
- if self.log_handler in stdout_logger.handlers:
262
- stdout_logger.removeHandler(self.log_handler)
263
- if self.log_handler in stderr_logger.handlers:
264
- stderr_logger.removeHandler(self.log_handler)
265
- else:
266
- if self.log_handler in self.root_logger.handlers:
267
- self.root_logger.removeHandler(self.log_handler)
280
+ if self.execution_filter:
281
+ self.log_handler.removeFilter(self.execution_filter)
282
+
283
+ if self.log_handler in self.root_logger.handlers:
284
+ self.root_logger.removeHandler(self.log_handler)
268
285
 
286
+ # Remove from stdout/stderr loggers
287
+ stdout_logger = logging.getLogger("stdout")
288
+ stderr_logger = logging.getLogger("stderr")
289
+ if self.log_handler in stdout_logger.handlers:
290
+ stdout_logger.removeHandler(self.log_handler)
291
+ if self.log_handler in stderr_logger.handlers:
292
+ stderr_logger.removeHandler(self.log_handler)
293
+
294
+ if not self.execution_id:
295
+ # Master execution: restore everything
269
296
  for logger_name in self.patched_loggers:
270
297
  logger = logging.getLogger(logger_name)
271
298
  if self.log_handler in logger.handlers:
@@ -278,6 +305,7 @@ class LogsInterceptor:
278
305
 
279
306
  self.log_handler.close()
280
307
 
308
+ # Only restore streams if we redirected them
281
309
  if self.original_stdout and self.original_stderr:
282
310
  sys.stdout = self.original_stdout
283
311
  sys.stderr = self.original_stderr
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath
3
- Version: 2.1.73
3
+ Version: 2.1.74
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
@@ -63,7 +63,7 @@ uipath/_cli/_push/sw_file_handler.py,sha256=iE8Sk1Z-9hxmLFFj3j-k4kTK6TzNFP6hUCmx
63
63
  uipath/_cli/_runtime/_contracts.py,sha256=D57cq5V5CZ9p13n_vRDHRcwyJYQUcJLlAMbAOzIiBNI,28932
64
64
  uipath/_cli/_runtime/_escalation.py,sha256=x3vI98qsfRA-fL_tNkRVTFXioM5Gv2w0GFcXJJ5eQtg,7981
65
65
  uipath/_cli/_runtime/_hitl.py,sha256=VKbM021nVg1HEDnTfucSLJ0LsDn83CKyUtVzofS2qTU,11369
66
- uipath/_cli/_runtime/_logging.py,sha256=iO0AG_tqUBp7aJZTK_ZgwV3fFvxbi9Rp1UOBn3F76lw,11684
66
+ uipath/_cli/_runtime/_logging.py,sha256=CIJNZH4S8SL980VI3XV9NIFdc97T-KJRT8QE7X1uWYw,12865
67
67
  uipath/_cli/_runtime/_runtime.py,sha256=gby9-avNNlEATEfSXtY8FfJ8nREsSCGA4wMgDlSXTDE,2297
68
68
  uipath/_cli/_runtime/_script_executor.py,sha256=PjbmEbyCMofGH2F85b8RFsxdV3Tqw0kVqdWOOk2ZLlI,9687
69
69
  uipath/_cli/_templates/.psmdcp.template,sha256=C7pBJPt98ovEljcBvGtEUGoWjjQhu9jls1bpYjeLOKA,611
@@ -165,8 +165,8 @@ uipath/tracing/_traced.py,sha256=yBIY05PCCrYyx50EIHZnwJaKNdHPNx-YTR1sHQl0a98,199
165
165
  uipath/tracing/_utils.py,sha256=qd7N56tg6VXQ9pREh61esBgUWLNA0ssKsE0QlwrRWFM,11974
166
166
  uipath/utils/__init__.py,sha256=VD-KXFpF_oWexFg6zyiWMkxl2HM4hYJMIUDZ1UEtGx0,105
167
167
  uipath/utils/_endpoints_manager.py,sha256=iRTl5Q0XAm_YgcnMcJOXtj-8052sr6jpWuPNz6CgT0Q,8408
168
- uipath-2.1.73.dist-info/METADATA,sha256=JMXtiT-80R6YqDxcl-MdGOYRi8HDuqGSh1EpcEJ7o_Q,6593
169
- uipath-2.1.73.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
170
- uipath-2.1.73.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
171
- uipath-2.1.73.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
172
- uipath-2.1.73.dist-info/RECORD,,
168
+ uipath-2.1.74.dist-info/METADATA,sha256=YI-VaC3UPoQGy3mDnKYd4in3JnlExWwD9QzMJdO-H6s,6593
169
+ uipath-2.1.74.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
170
+ uipath-2.1.74.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
171
+ uipath-2.1.74.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
172
+ uipath-2.1.74.dist-info/RECORD,,