Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8a154d4
AP-25245: add pixi port to python scripting node
marc-lehner Jan 6, 2026
1dc32b5
AP-25245: move ports to dedicated plugin
marc-lehner Jan 7, 2026
6a92016
AP-25245: use pixi run in pixiPythonCommand for all pixi environment …
marc-lehner Jan 13, 2026
b8e33b8
AP-25245: add pixi port to python view
marc-lehner Jan 14, 2026
01a5f0f
AP-25245: add pixi port to interactive execution
marc-lehner Jan 14, 2026
479a8de
AP-25245: replace pixi port with python port
marc-lehner Jan 19, 2026
cf23fd0
AP-25245: add progress for the python port installation and make it c…
marc-lehner Jan 21, 2026
762c2ab
AP-25245: deprecate PythonCommand and use PythonProcessProvider from …
marc-lehner Jan 26, 2026
5848e6b
AP-25245: only use import PixiPythonCommand from knime-conda (import …
marc-lehner Jan 26, 2026
3769dca
AP-25245: use debug instead of info log for trivial messages.
chaubold Jan 26, 2026
0352dd5
AP-25245: update all plugins to 5.11
marc-lehner Feb 10, 2026
491e243
AP-25245: move pixi code to python port
marc-lehner Feb 10, 2026
5716a0c
AP-25245: consistent nameing of python environment port and methods
marc-lehner Feb 11, 2026
5c2e693
AP-25245: rename pythonprocessprovider to externalprocessprovider
marc-lehner Feb 12, 2026
39a2a25
AP-25245: Code review and fixes
HedgehogCode Feb 12, 2026
d40a6f1
AP-25245: switch port order
marc-lehner Feb 17, 2026
17c0509
AP-25245: add env check to adjust prints for installing
marc-lehner Feb 17, 2026
e69d690
AP-25245: use isInstalled check to show correct progress in execution
marc-lehner Feb 17, 2026
07f5da9
AP-25245: Add missing import for javadoc
HedgehogCode Feb 18, 2026
72769e8
AP-25245: Remove unnecessary import
HedgehogCode Feb 18, 2026
23fc23d
AP-25245: Undo plugin dependency downgrades
HedgehogCode Feb 18, 2026
2969f3c
AP-25245: Fix formatting of PortsConfigurationUtils
HedgehogCode Feb 18, 2026
4b87ccc
AP-25245: Remove unused code
HedgehogCode Feb 18, 2026
36f1937
AP-25245: Fix javadoc of extractPythonEnvironmentPort
HedgehogCode Feb 18, 2026
98dc0c7
AP-25245: Use streams for simplified implementation of filterEnvironm…
HedgehogCode Feb 18, 2026
ae69a3d
AP-25245: Replace System.out.println with LOGGER.debug
HedgehogCode Feb 18, 2026
d83c14f
AP-25245: Remove unnecessary dataPortObjects filtering
HedgehogCode Feb 18, 2026
798e42e
AP-25245: Remove TODO comment
HedgehogCode Feb 18, 2026
0b1939d
AP-25245: Only get the pythonEnvironmentPort if the node has one
HedgehogCode Feb 18, 2026
da42a73
AP-25245: Use remainingProgress for output processing
HedgehogCode Feb 18, 2026
2f45e84
AP-25245: Add back suppression of rawtypes in pushNewFlowVariable
HedgehogCode Feb 18, 2026
4f3f8fa
AP-25245: Remove environment port handling from PortsConfigurationUtils
HedgehogCode Feb 18, 2026
833248d
AP-25245: Make pythonCommand in scripting service final
HedgehogCode Feb 18, 2026
ddcbd8a
AP-25245: Remove optional port type
HedgehogCode Feb 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion org.knime.python3.arrow.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ Require-Bundle: org.junit;bundle-version="[4.13.0,5.0.0)",
org.apache.commons.lang3;bundle-version="[3.9.0,4.0.0)",
org.knime.core.columnar;bundle-version="[5.6.0,6.0.0)",
org.knime.core.data.columnar;bundle-version="[5.6.0,6.0.0)",
org.knime.python3.testing;bundle-version="[5.6.0,6.0.0)"
org.knime.python3.testing;bundle-version="[5.6.0,6.0.0)",
org.knime.externalprocessprovider;bundle-version="[5.11.0,6.0.0)"
Automatic-Module-Name: org.knime.python3.arrow.tests
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@
import java.util.Collections;
import java.util.List;

import org.knime.externalprocessprovider.ExternalProcessProvider;
import org.knime.python3.DefaultPythonGateway;
import org.knime.python3.Python3SourceDirectory;
import org.knime.python3.PythonCommand;
import org.knime.python3.PythonDataSink;
import org.knime.python3.PythonDataSource;
import org.knime.python3.PythonEntryPoint;
Expand Down Expand Up @@ -83,7 +83,7 @@ private TestUtils() {
* @throws InterruptedException
*/
public static PythonGateway<ArrowTestsEntryPoint> openPythonGateway() throws IOException, InterruptedException {
final PythonCommand command = Python3TestUtils.getPythonCommand();
final ExternalProcessProvider command = Python3TestUtils.getPythonCommand();
final String launcherPath =
Paths.get(System.getProperty("user.dir"), "src/test/python", "tests_launcher.py").toString();
final PythonPath pythonPath = (new PythonPathBuilder()) //
Expand Down
3 changes: 2 additions & 1 deletion org.knime.python3.arrow.types.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Require-Bundle: org.knime.core.table;bundle-version="[5.6.0,6.0.0)",
org.knime.core.data.columnar;bundle-version="[5.6.0,6.0.0)",
com.fasterxml.jackson.core.jackson-databind;bundle-version="[2.12.1,3.0.0)",
org.knime.python3.types;bundle-version="[5.6.0,6.0.0)",
org.knime.python3.testing;bundle-version="[5.6.0,6.0.0)"
org.knime.python3.testing;bundle-version="[5.6.0,6.0.0)",
org.knime.externalprocessprovider;bundle-version="[5.11.0,6.0.0)"
Automatic-Module-Name: org.knime.python3.arrow.types.tests
Export-Package: org.knime.python3.arrow.types
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
import org.knime.core.table.schema.DataSpecs.DataSpecWithTraits;
import org.knime.core.table.schema.DefaultColumnarSchema;
import org.knime.core.table.schema.traits.LogicalTypeTrait;
import org.knime.externalprocessprovider.ExternalProcessProvider;
import org.knime.filehandling.core.connections.FSCategory;
import org.knime.filehandling.core.connections.FSLocation;
import org.knime.filehandling.core.data.location.FSLocationValue;
Expand All @@ -172,7 +173,6 @@
import org.knime.filehandling.core.data.location.cell.SimpleFSLocationCellFactory;
import org.knime.python3.DefaultPythonGateway;
import org.knime.python3.Python3SourceDirectory;
import org.knime.python3.PythonCommand;
import org.knime.python3.PythonDataSink;
import org.knime.python3.PythonDataSource;
import org.knime.python3.PythonEntryPoint;
Expand Down Expand Up @@ -893,7 +893,7 @@ interface TriConsumer<A, B, C> {

private static <E extends PythonEntryPoint> PythonGateway<E> openPythonGateway(final Class<E> entryPointClass,
final String launcherModule, final PythonModule... modules) throws IOException, InterruptedException {
final PythonCommand command = Python3TestUtils.getPythonCommand();
final ExternalProcessProvider command = Python3TestUtils.getPythonCommand();
final String launcherPath = Paths.get(System.getProperty("user.dir"), "src/test/python", launcherModule)
.toString();
final PythonPathBuilder builder = PythonPath.builder()//
Expand Down
3 changes: 2 additions & 1 deletion org.knime.python3.nodes/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ Require-Bundle: org.knime.core;bundle-version="[5.10.0,6.0.0)",
com.fasterxml.jackson.core.jackson-annotations;bundle-version="[2.13.2,3.0.0)",
org.knime.workflowservices;bundle-version="[5.10.0,6.0.0)",
org.apache.commons.lang3;bundle-version="[3.9.0,4.0.0)",
org.knime.gateway.impl;bundle-version="[5.10.0,6.0.0)"
org.knime.gateway.impl;bundle-version="[5.10.0,6.0.0)",
org.knime.externalprocessprovider;bundle-version="[5.11.0,6.0.0)"
Automatic-Module-Name: org.knime.python3.nodes
Eclipse-RegisterBuddy: org.knime.ext.py4j
Eclipse-BundleShape: dir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@

import org.knime.conda.prefs.CondaPreferences;
import org.knime.core.node.NodeLogger;
import org.knime.externalprocessprovider.ExternalProcessProvider;
import org.knime.python3.CondaPythonCommand;
import org.knime.python3.PythonCommand;
import org.knime.python3.SimplePythonCommand;
import org.yaml.snakeyaml.Yaml;

Expand Down Expand Up @@ -91,7 +91,7 @@ static Stream<Path> getPathsToCustomExtensions() {
.map(Optional::get);
}

static Optional<PythonCommand> getCustomPythonCommand(final String extensionId) {
static Optional<ExternalProcessProvider> getCustomPythonCommand(final String extensionId) {
return loadConfigs()//
.filter(e -> extensionId.equals(e.m_id))//
.findFirst()//
Expand Down Expand Up @@ -307,7 +307,7 @@ Optional<Path> getSrcPath() {
}
}

Optional<PythonCommand> getCommand() {
Optional<ExternalProcessProvider> getCommand() {
if (m_condaEnvPath != null) {
if (m_pythonExecutable != null) {
LOGGER.warnWithFormat("Both conda_env_path and python_executable are provided for extension '%s'."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@
import java.util.Objects;

import org.knime.conda.envbundling.environment.CondaEnvironmentRegistry;
import org.knime.externalprocessprovider.ExternalProcessProvider;
import org.knime.python3.Activator;
import org.knime.python3.BundledPythonCommand;
import org.knime.python3.FreshPythonGatewayFactory;
import org.knime.python3.Python3SourceDirectory;
import org.knime.python3.PythonCommand;
import org.knime.python3.PythonEntryPointUtils;
import org.knime.python3.PythonGateway;
import org.knime.python3.PythonGatewayFactory;
Expand Down Expand Up @@ -141,12 +141,12 @@ public PythonGateway<KnimeNodeBackend> create() throws IOException, InterruptedE
return gateway;
}

private static PythonCommand createCommand(final String extensionId, final String environmentName) {
private static ExternalProcessProvider createCommand(final String extensionId, final String environmentName) {
return PythonExtensionPreferences.getCustomPythonCommand(extensionId)//
.orElseGet(() -> getPythonCommandForEnvironment(environmentName));
}

private static PythonCommand getPythonCommandForEnvironment(final String environmentName) {
private static ExternalProcessProvider getPythonCommandForEnvironment(final String environmentName) {
final var environment = CondaEnvironmentRegistry.getEnvironment(environmentName);
if (environment == null) {
throw new IllegalStateException("Conda environment '" + environmentName + "' not found. "
Expand Down
4 changes: 3 additions & 1 deletion org.knime.python3.scripting.nodes/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Require-Bundle: org.knime.core;bundle-version="[5.11.0,6.0.0)",
org.eclipse.ui;bundle-version="3.119.0",
org.knime.conda;bundle-version="[5.11.0,6.0.0)",
org.knime.conda.envbundling;bundle-version="[5.10.0,6.0.0)",
org.knime.pixi.port;bundle-version="[5.11.0,6.0.0)",
org.knime.core.ui;bundle-version="[5.11.0,6.0.0)",
org.knime.workbench.editor;bundle-version="[5.10.0,6.0.0)",
org.apache.batik.util;bundle-version="[1.16.0,2.0.0)",
Expand All @@ -38,7 +39,8 @@ Require-Bundle: org.knime.core;bundle-version="[5.11.0,6.0.0)",
com.fasterxml.jackson.core.jackson-core;bundle-version="2.13.2",
com.fasterxml.jackson.core.jackson-databind;bundle-version="2.13.2",
org.eclipse.orbit.xml-apis-ext;bundle-version="[1.0.0,2.0.0)",
org.apache.commons.commons-io;bundle-version="[2.15.1,3.0.0)"
org.apache.commons.commons-io;bundle-version="[2.15.1,3.0.0)",
org.knime.externalprocessprovider;bundle-version="[5.11.0,6.0.0)"
Automatic-Module-Name: org.knime.python3.scripting.nodes
Export-Package: org.knime.python3.scripting.nodes.prefs
Eclipse-RegisterBuddy: org.knime.ext.py4j
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import org.knime.core.util.PathUtils;
import org.knime.core.util.asynclose.AsynchronousCloseableTracker;
import org.knime.core.webui.node.view.NodeView;
import org.knime.externalprocessprovider.ExternalProcessProvider;
import org.knime.python2.PythonCommand;
import org.knime.python2.PythonModuleSpec;
import org.knime.python2.PythonVersion;
Expand Down Expand Up @@ -381,14 +382,14 @@ private void pushNewFlowVariable(final FlowVariable variable) {
}

/**
* Wraps a {@link org.knime.python3.PythonCommand} into the legacy implementation for using it in a
* Wraps a {@link ExternalProcessProvider} into the legacy implementation for using it in a
* {@link PythonKernelBackend}.
*/
private static final class LegacyPythonCommand implements PythonCommand {

private final org.knime.python3.PythonCommand m_pythonCommand;
private final ExternalProcessProvider m_pythonCommand;

private LegacyPythonCommand(final org.knime.python3.PythonCommand pythonCommand) {
private LegacyPythonCommand(final ExternalProcessProvider pythonCommand) {
m_pythonCommand = pythonCommand;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
import org.knime.conda.prefs.CondaPreferences;
import org.knime.core.node.NodeLogger;
import org.knime.core.node.defaultnodesettings.SettingsModelString;
import org.knime.externalprocessprovider.ExternalProcessProvider;
import org.knime.python3.CondaPythonCommand;
import org.knime.python3.PythonCommand;

/**
* Copied and modified from org.knime.python2.config.
Expand Down Expand Up @@ -113,7 +113,7 @@ public ObservableValue<CondaEnvironmentIdentifier[]> getAvailableEnvironments()
}

@Override
public PythonCommand getPythonCommand() {
public ExternalProcessProvider getPythonCommand() {
return new CondaPythonCommand(CondaPreferences.getCondaInstallationDirectory(),
m_environmentDirectory.getStringValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
package org.knime.python3.scripting.nodes.prefs;

import org.knime.core.node.defaultnodesettings.SettingsModelString;
import org.knime.python3.PythonCommand;
import org.knime.externalprocessprovider.ExternalProcessProvider;
import org.knime.python3.SimplePythonCommand;

/**
Expand Down Expand Up @@ -79,7 +79,7 @@ public SettingsModelString getExecutablePath() {
}

@Override
public PythonCommand getPythonCommand() {
public ExternalProcessProvider getPythonCommand() {
return new SimplePythonCommand(m_pythonPath.getStringValue());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.knime.conda.CondaEnvironmentIdentifier;
import org.knime.conda.prefs.CondaPreferences;
import org.knime.externalprocessprovider.ExternalProcessProvider;
import org.knime.python3.BundledPythonCommand;
import org.knime.python3.PythonCommand;

/**
* Convenience front-end of the preference-based configuration of the Python integration.
Expand Down Expand Up @@ -110,7 +110,7 @@ public static PythonEnvironmentType getEnvironmentTypePreference() {
/**
* @return The currently selected default Python command.
*/
public static PythonCommand getPythonCommandPreference() {
public static ExternalProcessProvider getPythonCommandPreference() {
final var envType = getEnvironmentTypePreference();
PythonEnvironmentsConfig environmentsConfig;

Expand All @@ -124,7 +124,7 @@ public static PythonCommand getPythonCommandPreference() {
}

/**
* @return The {@link PythonCommand} for the installed bundled environment.
* @return The {@link ExternalProcessProvider} for the installed bundled environment.
*/
public static BundledPythonCommand getBundledPythonCommand() {
return getBundledCondaEnvironmentConfig().getPythonCommand();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

import org.knime.core.node.defaultnodesettings.SettingsModelBoolean;
import org.knime.core.node.defaultnodesettings.SettingsModelString;
import org.knime.python3.PythonCommand;
import org.knime.externalprocessprovider.ExternalProcessProvider;

/**
* Copied from org.knime.python2.config.
Expand All @@ -63,7 +63,7 @@ interface PythonEnvironmentConfig extends PythonConfig {
/**
* @return The command that executes Python in the Python environment configured by this instance.
*/
PythonCommand getPythonCommand();
ExternalProcessProvider getPythonCommand();

/**
* @return If the Python environment configured by this instance is currently the default environment. Not meant for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
import org.knime.core.node.NodeLogger;
import org.knime.core.util.FileUtil;
import org.knime.core.util.Pair;
import org.knime.python3.PythonCommand;
import org.knime.externalprocessprovider.ExternalProcessProvider;

/**
* Copied from org.knime.python2.
Expand Down Expand Up @@ -94,7 +94,7 @@ final class PythonKernelTester {
* Caches previous test results. Mapping from the Python command that was tested to a list of additional required
* modules that were tested along the command and the test results of these combinations of command and modules.
*/
private static final Map<PythonCommand, List<Pair<Set<PythonModuleSpec>, PythonKernelTestResult>>> TEST_RESULTS =
private static final Map<ExternalProcessProvider, List<Pair<Set<PythonModuleSpec>, PythonKernelTestResult>>> TEST_RESULTS =
new ConcurrentHashMap<>();

private static String getPythonKernelTesterPath() throws IOException {
Expand All @@ -119,7 +119,7 @@ private PythonKernelTester() {
* @param force Force the test to be rerun again even if the same configuration was successfully tested before.
* @return The results of the installation test.
*/
public static PythonKernelTestResult testPython3Installation(final PythonCommand python3Command,
public static PythonKernelTestResult testPython3Installation(final ExternalProcessProvider python3Command,
final Collection<PythonModuleSpec> additionalRequiredModules, final boolean force) {
return testPythonInstallation(python3Command, PYTHON_MAJOR_VERSION_3, PYTHON_MINIMUM_VERSION_3,
additionalRequiredModules, Collections.emptyList(), force);
Expand All @@ -128,7 +128,7 @@ public static PythonKernelTestResult testPython3Installation(final PythonCommand
/**
* @param minimumVersion May be {@code null} in the case where no minimum version is required.
*/
private static synchronized PythonKernelTestResult testPythonInstallation(final PythonCommand pythonCommand,
private static synchronized PythonKernelTestResult testPythonInstallation(final ExternalProcessProvider pythonCommand,
final String majorVersion, final String minimumVersion,
final Collection<PythonModuleSpec> additionalRequiredModules,
final Collection<PythonModuleSpec> additionalOptionalModules, final boolean force) {
Expand Down Expand Up @@ -189,7 +189,7 @@ private static synchronized PythonKernelTestResult testPythonInstallation(final
return testResults;
}

private static PythonKernelTestResult getPreviousTestResultsIfApplicable(final PythonCommand pythonCommand,
private static PythonKernelTestResult getPreviousTestResultsIfApplicable(final ExternalProcessProvider pythonCommand,
final Set<PythonModuleSpec> additionalRequiredModules) {
// If a previous, appropriate Python test already succeeded, we will not have to run it again and return the
// old results here (except if we're forced to).
Expand All @@ -209,7 +209,7 @@ private static PythonKernelTestResult getPreviousTestResultsIfApplicable(final P
return null;
}

private static Process runPythonKernelTester(final PythonCommand pythonCommand, final String majorVersion,
private static Process runPythonKernelTester(final ExternalProcessProvider pythonCommand, final String majorVersion,
final String minimumVersion, final Collection<PythonModuleSpec> additionalRequiredModules,
final Collection<PythonModuleSpec> additionalOptionalModules, final StringBuilder testLogger)
throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
import org.knime.conda.CondaEnvironmentPropagation.CondaEnvironmentType;
import org.knime.conda.prefs.CondaPreferences;
import org.knime.core.node.workflow.FlowObjectStack;
import org.knime.externalprocessprovider.ExternalProcessProvider;
import org.knime.python3.CondaPythonCommand;
import org.knime.python3.PythonCommand;
import org.knime.python3.SimplePythonCommand;
import org.knime.python3.scripting.nodes.prefs.Python3ScriptingPreferences;
import org.knime.python3.scripting.nodes2.PythonScriptingService.ExecutableOption;
Expand All @@ -83,7 +83,7 @@ static Map<String, ExecutableOption> getExecutableOptions(final FlowObjectStack
}

/** Get the PythonCommand from the selected option */
static PythonCommand getPythonCommand(final ExecutableOption option) {
static ExternalProcessProvider getPythonCommand(final ExecutableOption option) {
switch (option.type) {
case CONDA_ENV_VAR:
return commandForConda(option.condaEnvDir);
Expand All @@ -106,7 +106,7 @@ static PythonCommand getPythonCommand(final ExecutableOption option) {
}

/** Get the PythonCommand from the given settings String */
static PythonCommand getPythonCommand(final String commandString) {
static ExternalProcessProvider getPythonCommand(final String commandString) {
if (commandString == null || EXEC_SELECTION_PREF_ID.equals(commandString)) {
// Nothing configured -> Use preferences
return commandForPreferences();
Expand All @@ -126,7 +126,7 @@ static boolean isPathToCondaEnv(final String commandString) {

private static ExecutableOption getPreferenceOption() {
return new ExecutableOption(getPreferenceOptionType(), EXEC_SELECTION_PREF_ID,
commandForPreferences().getPythonExecutablePath().toString(), null, null);
commandForPreferences().getExecutablePath().toString(), null, null);
}

private static ExecutableOptionType getPreferenceOptionType() {
Expand Down Expand Up @@ -161,15 +161,15 @@ private static Stream<ExecutableOption> getCondaFlowVariableOptions(final FlowOb
}
}

private static PythonCommand commandForConda(final String condaEnvDir) {
private static ExternalProcessProvider commandForConda(final String condaEnvDir) {
return new CondaPythonCommand(CondaPreferences.getCondaInstallationDirectory(), condaEnvDir);
}

private static PythonCommand commandForString(final String pythonExecutable) {
private static ExternalProcessProvider commandForString(final String pythonExecutable) {
return new SimplePythonCommand(pythonExecutable);
}

private static PythonCommand commandForPreferences() {
private static ExternalProcessProvider commandForPreferences() {
return Python3ScriptingPreferences.getPythonCommandPreference();
}
}
Loading