diff --git a/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java b/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java index e482585c46b..8e881f63764 100644 --- a/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java +++ b/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java @@ -27,6 +27,7 @@ import org.apache.zeppelin.interpreter.jupyter.proto.ExecuteStatus; import org.apache.zeppelin.interpreter.remote.RemoteInterpreterUtils; import org.apache.zeppelin.jupyter.JupyterKernelInterpreter; +import org.apache.zeppelin.jupyter.PythonPackagePredicate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import py4j.GatewayServer; @@ -67,10 +68,16 @@ public String getKernelName() { } @Override - public List getRequiredPackages() { - List requiredPackages = super.getRequiredPackages(); - requiredPackages.add("ipython"); - requiredPackages.add("ipykernel"); + public List> getRequiredPackagesPredicates() { + List> requiredPackages = super.getRequiredPackagesPredicates(); + requiredPackages.add( + new PythonPackagePredicate<>("ipython", + packages -> packages.contains("ipython ") || + packages.contains("ipython="))); + requiredPackages.add( + new PythonPackagePredicate<>("ipykernel", + packages -> packages.contains("ipykernel ") || + packages.contains("ipykernel="))); return requiredPackages; } diff --git a/zeppelin-jupyter-interpreter/src/main/java/org/apache/zeppelin/jupyter/JupyterKernelInterpreter.java b/zeppelin-jupyter-interpreter/src/main/java/org/apache/zeppelin/jupyter/JupyterKernelInterpreter.java index 38a40617002..a954e1dfa9a 100644 --- a/zeppelin-jupyter-interpreter/src/main/java/org/apache/zeppelin/jupyter/JupyterKernelInterpreter.java +++ b/zeppelin-jupyter-interpreter/src/main/java/org/apache/zeppelin/jupyter/JupyterKernelInterpreter.java @@ -96,11 +96,28 @@ public String getKernelName() { return this.kernel; } - public List getRequiredPackages() { - List requiredPackages = new ArrayList<>(); - requiredPackages.add("jupyter-client"); - requiredPackages.add("grpcio"); - requiredPackages.add("protobuf"); + public List> getRequiredPackagesPredicates() { + /** + * Example line, if the Python package is installed with pip: + * grpcio==1.18.0 + * Example line, if the Python package is installed with conda: + * grpcio @ file:///home/conda/feedstock_root/build_artifacts/grpcio_1604365513151/work + */ + List> requiredPackages = new ArrayList<>(); + requiredPackages.add( + new PythonPackagePredicate<>("jupyter-client or jupyter_client", + packages -> packages.contains("jupyter-client ") || + packages.contains("jupyter-client=") || + packages.contains("jupyter_client ") || + packages.contains("jupyter_client="))); + requiredPackages.add( + new PythonPackagePredicate<>("grpcio", + packages -> packages.contains("grpcio ") || + packages.contains("grpcio="))); + requiredPackages.add( + new PythonPackagePredicate<>("protobuf", + packages -> packages.contains("protobuf ") || + packages.contains("protobuf="))); return requiredPackages; } @@ -172,16 +189,9 @@ public String checkKernelPrerequisite(String pythonExec) { } try (FileInputStream in = new FileInputStream(stdoutFile)) { String freezeOutput = IOUtils.toString(in, StandardCharsets.UTF_8); - for (String packageName : getRequiredPackages()) { - /** - * Example line, if the Python package is installed with pip: - * grpcio==1.18.0 - * Example line, if the Python package is installed with conda: - * grpcio @ file:///home/conda/feedstock_root/build_artifacts/grpcio_1604365513151/work - */ - if (!freezeOutput.contains(packageName + "=") && - !freezeOutput.contains(packageName + " ")) { - return packageName + " is not installed, installed packages:\n" + freezeOutput; + for (PythonPackagePredicate packagePredicate : getRequiredPackagesPredicates()) { + if (!packagePredicate.test(freezeOutput)) { + return packagePredicate + " is not installed, installed packages:\n" + freezeOutput; } } LOGGER.info("Prerequisite for kernel {} is met", getKernelName()); diff --git a/zeppelin-jupyter-interpreter/src/main/java/org/apache/zeppelin/jupyter/PythonPackagePredicate.java b/zeppelin-jupyter-interpreter/src/main/java/org/apache/zeppelin/jupyter/PythonPackagePredicate.java new file mode 100644 index 00000000000..9577d32d5ad --- /dev/null +++ b/zeppelin-jupyter-interpreter/src/main/java/org/apache/zeppelin/jupyter/PythonPackagePredicate.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.jupyter; + +import java.util.function.Predicate; + +public class PythonPackagePredicate implements Predicate { + private final String name; + private final Predicate predicate; + + public PythonPackagePredicate(String name, Predicate predicate) { + this.name = name; + this.predicate = predicate; + } + + @Override + public boolean test(T t) { + return predicate.test(t); + } + + @Override + public String toString() { + return name; + } +}