diff --git a/packages/@n8n/task-runner-python/src/message_serde.py b/packages/@n8n/task-runner-python/src/message_serde.py index 0bf8a41460..e2262268c5 100644 --- a/packages/@n8n/task-runner-python/src/message_serde.py +++ b/packages/@n8n/task-runner-python/src/message_serde.py @@ -50,6 +50,7 @@ def _parse_task_settings(d: dict) -> BrokerTaskSettings: workflow_id = settings_dict.get("workflowId", "Unknown") node_name = settings_dict.get("nodeName", "Unknown") node_id = settings_dict.get("nodeId", "Unknown") + can_log = settings_dict.get("canLog", False) except KeyError as e: raise ValueError(f"Missing field in task settings message: {e}") @@ -64,6 +65,7 @@ def _parse_task_settings(d: dict) -> BrokerTaskSettings: workflow_id=workflow_id, node_name=node_name, node_id=node_id, + can_log=can_log, ), ) diff --git a/packages/@n8n/task-runner-python/src/message_types/broker.py b/packages/@n8n/task-runner-python/src/message_types/broker.py index 91cee692bc..50a0ad9221 100644 --- a/packages/@n8n/task-runner-python/src/message_types/broker.py +++ b/packages/@n8n/task-runner-python/src/message_types/broker.py @@ -43,6 +43,7 @@ class TaskSettings: workflow_id: str node_name: str node_id: str + can_log: bool @dataclass diff --git a/packages/@n8n/task-runner-python/src/task_executor.py b/packages/@n8n/task-runner-python/src/task_executor.py index 653fcdbb40..2291ace814 100644 --- a/packages/@n8n/task-runner-python/src/task_executor.py +++ b/packages/@n8n/task-runner-python/src/task_executor.py @@ -35,6 +35,7 @@ class TaskExecutor: stdlib_allow: Set[str], external_allow: Set[str], builtins_deny: set[str], + can_log: bool, ): """Create a subprocess for executing a Python code task and a queue for communication.""" @@ -47,7 +48,15 @@ class TaskExecutor: queue = MULTIPROCESSING_CONTEXT.Queue() process = MULTIPROCESSING_CONTEXT.Process( target=fn, - args=(code, items, queue, stdlib_allow, external_allow, builtins_deny), + args=( + code, + items, + queue, + stdlib_allow, + external_allow, + builtins_deny, + can_log, + ), ) return process, queue @@ -114,6 +123,7 @@ class TaskExecutor: stdlib_allow: Set[str], external_allow: Set[str], builtins_deny: set[str], + can_log: bool, ): """Execute a Python code task in all-items mode.""" @@ -129,7 +139,9 @@ class TaskExecutor: globals = { "__builtins__": TaskExecutor._filter_builtins(builtins_deny), "_items": items, - "print": TaskExecutor._create_custom_print(print_args), + "print": TaskExecutor._create_custom_print(print_args) + if can_log + else print, } exec(code, globals) @@ -149,6 +161,7 @@ class TaskExecutor: stdlib_allow: Set[str], external_allow: Set[str], builtins_deny: set[str], + can_log: bool, ): """Execute a Python code task in per-item mode.""" @@ -167,7 +180,9 @@ class TaskExecutor: globals = { "__builtins__": TaskExecutor._filter_builtins(builtins_deny), "_item": item, - "print": TaskExecutor._create_custom_print(print_args), + "print": TaskExecutor._create_custom_print(print_args) + if can_log + else print, } exec(compiled_code, globals) diff --git a/packages/@n8n/task-runner-python/src/task_runner.py b/packages/@n8n/task-runner-python/src/task_runner.py index 73db8db3c4..84c86e9689 100644 --- a/packages/@n8n/task-runner-python/src/task_runner.py +++ b/packages/@n8n/task-runner-python/src/task_runner.py @@ -237,6 +237,7 @@ class TaskRunner: stdlib_allow=self.opts.stdlib_allow, external_allow=self.opts.external_allow, builtins_deny=self.opts.builtins_deny, + can_log=task_settings.can_log, ) task_state.process = process diff --git a/packages/nodes-base/nodes/Code/PythonTaskRunnerSandbox.ts b/packages/nodes-base/nodes/Code/PythonTaskRunnerSandbox.ts index 377c038fae..c5973aa175 100644 --- a/packages/nodes-base/nodes/Code/PythonTaskRunnerSandbox.ts +++ b/packages/nodes-base/nodes/Code/PythonTaskRunnerSandbox.ts @@ -38,6 +38,9 @@ export class PythonTaskRunnerSandbox { nodeName: node.name, workflowId: workflow.id, workflowName: workflow.name, + + /** Whether this task can log to the browser console. */ + canLog: this.executeFunctions.getMode() === 'manual', }; const executionResult = await this.executeFunctions.startJob(