Skip to content

Conversation

@marc-lehner
Copy link
Contributor

Add support for the new python environment provider node and it's pixi port object to the python scripts

@marc-lehner marc-lehner requested a review from a team as a code owner January 26, 2026 12:38
@marc-lehner marc-lehner requested review from Copilot and knime-ghub-bot and removed request for a team January 26, 2026 12:38
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for a new Python environment provider node with a Pixi port object, integrating it into the Python scripting nodes ecosystem. The changes enable Python script nodes to receive Python environments through an optional input port instead of only relying on configured preferences.

Changes:

  • Introduced PythonProcessProvider as a replacement interface for the deprecated PythonCommand to support multiple environment sources
  • Added optional Python environment port support to Python Script and Python View nodes
  • Implemented environment port extraction and installation logic with progress reporting

Reviewed changes

Copilot reviewed 41 out of 41 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
org.knime.python3/src/main/java/org/knime/python3/PythonCommand.java Deprecated PythonCommand interface, now extends PythonProcessProvider for backward compatibility
org.knime.python3/src/main/java/org/knime/python3/SimplePythonCommand.java Updated documentation to reference PythonProcessProvider
org.knime.python3/src/main/java/org/knime/python3/QueuedPythonGatewayFactory.java Refactored to use PythonProcessProvider instead of PythonCommand
org.knime.python3/src/main/java/org/knime/python3/PythonGatewayFactory.java Updated gateway description to work with PythonProcessProvider
org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes2/script/PythonScriptNodeFactory.java Added optional Python environment port to Python Script node
org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes2/view/PythonViewNodeFactory.java Added optional Python environment port to Python View node
org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes2/PythonScriptNodeModel.java Implemented environment port extraction and prioritization over configured Python command
org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes2/PythonScriptingService.java Added environment port handling for interactive sessions
org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes2/PythonScriptingSession.java Added PythonCommandAdapter to bridge PythonProcessProvider to legacy PythonCommand
org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes/PortsConfigurationUtils.java Added utility methods for environment port detection and installation
org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes2/PythonIOUtils.java Updated to filter out environment ports from data processing
org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes2/PythonScriptingInputOutputModelUtils.java Added logic to skip environment ports in input/output model generation

Copilot AI review requested due to automatic review settings January 26, 2026 17:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 41 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes2/script/PythonScriptNodeFactory.java:1

  • The variable pythonEnvClass is declared but never used on line 130 and 139. This appears to be a leftover from development and should be removed to reduce code clutter.
/*

org.knime.python3.scripting.nodes/src/main/java/org/knime/python3/scripting/nodes2/view/PythonViewNodeFactory.java:1

  • The variable pythonEnvClass is declared on line 91 in the view factory but never used. This appears to be a leftover from development and should be removed to reduce code clutter.
/*

@marc-lehner marc-lehner force-pushed the enh/AP-25245-pixi-env-creator branch 2 times, most recently from 5297ab6 to a396f21 Compare February 10, 2026 14:29
Copilot AI review requested due to automatic review settings February 10, 2026 15:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 41 changed files in this pull request and generated 13 comments.

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
18.5% Coverage on New Code (required ≥ 85%)
13.2% Duplication on New Code (required ≤ 1%)

See analysis details on SonarQube Cloud

Copilot AI review requested due to automatic review settings February 11, 2026 08:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 41 changed files in this pull request and generated 9 comments.

@marc-lehner marc-lehner force-pushed the enh/AP-25245-pixi-env-creator branch from 732d9ac to 15d85da Compare February 11, 2026 09:37
Copilot AI review requested due to automatic review settings February 11, 2026 10:39
@marc-lehner marc-lehner force-pushed the enh/AP-25245-pixi-env-creator branch from 15d85da to 3e4affb Compare February 11, 2026 10:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 41 changed files in this pull request and generated 3 comments.

Comment on lines +235 to +237
final PortObject[] filtered = new PortObject[inObjects.length - 1];
int filteredIndex = 0;
for (int i = 0; i < inTypes.length && i < inObjects.length; i++) {
if (!isPythonEnvironmentPort(inTypes[i])) {
filtered[filteredIndex++] = inObjects[i];
}
}
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filterEnvironmentPort assumes exactly one environment port and blindly allocates inObjects.length - 1. If the configuration ever contains 0 or >1 environment ports (e.g., future changes, misconfiguration, or different port typing), this can either drop a data port or return an array containing trailing nulls (risking downstream NPEs). Allocate the filtered array by counting non-environment ports (based on inTypes) and fill it accordingly, or build a dynamic list and convert to array to guarantee correct sizing.

Suggested change
final PortObject[] filtered = new PortObject[inObjects.length - 1];
int filteredIndex = 0;
for (int i = 0; i < inTypes.length && i < inObjects.length; i++) {
if (!isPythonEnvironmentPort(inTypes[i])) {
filtered[filteredIndex++] = inObjects[i];
}
}
final int max = Math.min(inTypes.length, inObjects.length);
// First pass: count non-environment ports within the overlapping range
int nonEnvCount = 0;
for (int i = 0; i < max; i++) {
if (!isPythonEnvironmentPort(inTypes[i])) {
nonEnvCount++;
}
}
// Any remaining PortObjects beyond the typed range are treated as non-environment ports
if (inObjects.length > max) {
nonEnvCount += inObjects.length - max;
}
final PortObject[] filtered = new PortObject[nonEnvCount];
int filteredIndex = 0;
// Second pass: copy non-environment ports from the overlapping range
for (int i = 0; i < max; i++) {
if (!isPythonEnvironmentPort(inTypes[i])) {
filtered[filteredIndex++] = inObjects[i];
}
}
// Third pass: copy any remaining ports beyond the typed range
for (int i = max; i < inObjects.length; i++) {
filtered[filteredIndex++] = inObjects[i];
}

Copilot uses AI. Check for mistakes.
Comment on lines +201 to +206
public static PythonEnvironmentPortObject extractPythonEnvironmentPort(
final PortsConfiguration config, final PortObject[] inObjects) {
final PortType[] inTypes = config.getInputPorts();
for (int i = 0; i < inTypes.length; i++) {
if (isPythonEnvironmentPort(inTypes[i]) && PythonEnvironmentPortObject.isPythonEnvironmentPortObject(inObjects[i])) {
return (PythonEnvironmentPortObject) inObjects[i];
}
}
return null;
}
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This utility method hard-links to PythonEnvironmentPortObject in its signature and body even though org.knime.pixi.port is declared optional. In OSGi, such direct type references can still trigger NoClassDefFoundError at class load/link time (not just at execution), which would prevent the scripting nodes bundle from loading when the optional bundle isn’t available. To keep the dependency truly optional, avoid exposing Pixi types in public method signatures and isolate direct references behind reflection or a separate fragment/bundle that is only resolved when org.knime.pixi.port is present.

Copilot uses AI. Check for mistakes.
Comment on lines 196 to 211
if (m_ports.hasPythonEnvironmentPort()) {
PortsConfigurationUtils.installPythonEnvironmentIfPresent(getPortsConfiguration(), inObjects, exec);
}

// Extract Python command from environment port if connected, otherwise use configured command
final PythonProcessProvider pythonCommand;
final PythonProcessProvider pythonCommandFromEnv = PythonEnvironmentPortObject.extractPythonCommand(
PortsConfigurationUtils.extractPythonEnvironmentPort(getPortsConfiguration(), inObjects));
if (pythonCommandFromEnv != null) {
LOGGER.debug("Using Python from environment port");
pythonCommand = pythonCommandFromEnv;
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New behavior is introduced for (1) early environment installation and (2) precedence of the environment-port-provided Python over the configured executable. Please add tests that cover: env port connected vs. not connected; extraction failure fallback to executable selection; and ensuring the environment port is not forwarded as a data input to the session (i.e., input port filtering). This helps prevent regressions given the multiple new paths and optional-dependency behavior.

Copilot uses AI. Check for mistakes.
@marc-lehner marc-lehner force-pushed the enh/AP-25245-pixi-env-creator branch from 3e4affb to 68c0942 Compare February 11, 2026 14:20
@marc-lehner marc-lehner force-pushed the enh/AP-25245-pixi-env-creator branch from 68c0942 to d461935 Compare February 11, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants