You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by mo...@apache.org on 2017/03/20 02:49:18 UTC

zeppelin git commit: [HOTFIX] Dynamic form in python interpreter

Repository: zeppelin
Updated Branches:
  refs/heads/master 632815c35 -> 1972a5862


[HOTFIX] Dynamic form in python interpreter

### What is this PR for?
https://github.com/apache/zeppelin/pull/2106 rewrote python interpreter. But dynamic form feature is not rewritten correctly.

### What type of PR is it?
Hot Fix

### Todos
* [x] - Bring dynamic form back

### What is the Jira issue?
https://github.com/apache/zeppelin/pull/2106

### How should this be tested?
run

```
%python
print("Hello "+z.input("name", "sun"))
```

```
%python
print("Hello "+z.select("day", [("1","mon"),
                                ("2","tue"),
                                ("3","wed"),
                                ("4","thurs"),
                                ("5","fri"),
                                ("6","sat"),
                                ("7","sun")]))
```

```
%python
options = [("apple","Apple"), ("banana","Banana"), ("orange","Orange")]
print("Hello "+ " and ".join(z.checkbox("fruit", options, ["apple"])))
```

### Questions:
* Does the licenses files need update? no
* Is there breaking changes for older versions? no
* Does this needs documentation? no

Author: Lee moon soo <mo...@apache.org>

Closes #2155 from Leemoonsoo/python_get_interpreter_context and squashes the following commits:

c5e584a [Lee moon soo] fix matplotlib display error on python 3.4
3e6603b [Lee moon soo] correctly handle zeppelin.python property.
5be8db4 [Lee moon soo] Expose a method to get InterpreterOutput, so user can call InterpreterOutput.clear()
a405a93 [Lee moon soo] implement dynamic form


Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/1972a586
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/1972a586
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/1972a586

Branch: refs/heads/master
Commit: 1972a58620b16bc4ec54191fb8660cf274647bd8
Parents: 632815c
Author: Lee moon soo <mo...@apache.org>
Authored: Sat Mar 18 10:10:00 2017 -0700
Committer: Lee moon soo <mo...@apache.org>
Committed: Sun Mar 19 19:49:02 2017 -0700

----------------------------------------------------------------------
 interpreter/lib/python/backend_zinline.py       |  6 +++-
 .../python/PythonDockerInterpreter.java         |  5 +--
 .../zeppelin/python/PythonInterpreter.java      | 17 ++++++++--
 .../main/resources/python/zeppelin_python.py    | 35 +++++++++++++++-----
 .../main/resources/python/zeppelin_pyspark.py   |  3 ++
 .../interpreter/InterpreterContext.java         |  4 +++
 6 files changed, 56 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/1972a586/interpreter/lib/python/backend_zinline.py
----------------------------------------------------------------------
diff --git a/interpreter/lib/python/backend_zinline.py b/interpreter/lib/python/backend_zinline.py
index adc5fd9..1c84699 100644
--- a/interpreter/lib/python/backend_zinline.py
+++ b/interpreter/lib/python/backend_zinline.py
@@ -18,6 +18,7 @@
 
 from __future__ import print_function
 
+import sys
 import uuid
 import warnings
 import base64
@@ -94,7 +95,10 @@ class FigureCanvasZInline(FigureCanvasAgg):
         buf = BytesIO()
         self.print_figure(buf, **kwargs)
         fmt = fmt.encode()
-        byte_str = b"data:image/%s;base64," %fmt
+        if sys.version_info >= (3, 4) and sys.version_info < (3, 5):
+            byte_str = bytes("data:image/%s;base64," %fmt, "utf-8")
+        else:
+            byte_str = b"data:image/%s;base64," %fmt
         byte_str += base64.b64encode(buf.getvalue())
             
         # Python3 forces all strings to default to unicode, but for raster image

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/1972a586/python/src/main/java/org/apache/zeppelin/python/PythonDockerInterpreter.java
----------------------------------------------------------------------
diff --git a/python/src/main/java/org/apache/zeppelin/python/PythonDockerInterpreter.java b/python/src/main/java/org/apache/zeppelin/python/PythonDockerInterpreter.java
index 582debd..cb0f620 100644
--- a/python/src/main/java/org/apache/zeppelin/python/PythonDockerInterpreter.java
+++ b/python/src/main/java/org/apache/zeppelin/python/PythonDockerInterpreter.java
@@ -89,8 +89,9 @@ public class PythonDockerInterpreter extends Interpreter {
           mountPythonScript +
           mountPy4j +
           "-e PYTHONPATH=\"" + pythonPath + "\" " +
-          image +
-          " python /_zeppelin_tmp/" + pythonScript.getName());
+          image + " " +
+          getPythonInterpreter().getPythonBindPath() + " " +
+          "/_zeppelin_tmp/" + pythonScript.getName());
       restartPythonProcess();
       out.clear();
       return new InterpreterResult(InterpreterResult.Code.SUCCESS, "\"" + image + "\" activated");

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/1972a586/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
----------------------------------------------------------------------
diff --git a/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java b/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
index f825568..df62406 100644
--- a/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
+++ b/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
@@ -395,6 +395,10 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
     }
   }
 
+  public InterpreterContext getCurrentInterpreterContext() {
+    return context;
+  }
+
   public void interrupt() throws IOException {
     if (pythonPid > -1) {
       logger.info("Sending SIGINT signal to PID : " + pythonPid);
@@ -440,14 +444,23 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
     pythonCommand = cmd;
   }
 
-  public String getPythonCommand() {
+  private String getPythonCommand() {
     if (pythonCommand == null) {
-      return DEFAULT_ZEPPELIN_PYTHON;
+      return getPythonBindPath();
     } else {
       return pythonCommand;
     }
   }
 
+  public String getPythonBindPath() {
+    String path = getProperty("zeppelin.python");
+    if (path == null) {
+      return DEFAULT_ZEPPELIN_PYTHON;
+    } else {
+      return path;
+    }
+  }
+
   private Job getRunningJob(String paragraphId) {
     Job foundJob = null;
     Collection<Job> jobsRunning = getScheduler().getJobsRunning();

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/1972a586/python/src/main/resources/python/zeppelin_python.py
----------------------------------------------------------------------
diff --git a/python/src/main/resources/python/zeppelin_python.py b/python/src/main/resources/python/zeppelin_python.py
index 0a36cba..a537c5d 100644
--- a/python/src/main/resources/python/zeppelin_python.py
+++ b/python/src/main/resources/python/zeppelin_python.py
@@ -48,25 +48,41 @@ class Logger(object):
 
 
 class PyZeppelinContext(object):
-  """ If py4j is detected, these class will be override
-      with the implementation in bootstrap_input.py
+  """ A context impl that uses Py4j to communicate to JVM
   """
-  errorMsg = "You must install py4j Python module " \
-             "(pip install py4j) to use Zeppelin dynamic forms features"
 
-  def __init__(self):
+  def __init__(self, z):
+    self.z = z
+    self.paramOption = gateway.jvm.org.apache.zeppelin.display.Input.ParamOption
+    self.javaList = gateway.jvm.java.util.ArrayList
     self.max_result = 1000
     self._displayhook = lambda *args: None
     self._setup_matplotlib()
 
+  def getInterpreterContext(self):
+    return self.z.getCurrentInterpreterContext()
+
   def input(self, name, defaultValue=""):
-    print(self.errorMsg)
+    return self.z.getGui().input(name, defaultValue)
 
   def select(self, name, options, defaultValue=""):
-    print(self.errorMsg)
+    javaOptions = gateway.new_array(self.paramOption, len(options))
+    i = 0
+    for tuple in options:
+      javaOptions[i] = self.paramOption(tuple[0], tuple[1])
+      i += 1
+    return self.z.getGui().select(name, defaultValue, javaOptions)
 
   def checkbox(self, name, options, defaultChecked=[]):
-    print(self.errorMsg)
+    javaOptions = gateway.new_array(self.paramOption, len(options))
+    i = 0
+    for tuple in options:
+      javaOptions[i] = self.paramOption(tuple[0], tuple[1])
+      i += 1
+    javaDefaultCheck = self.javaList()
+    for check in defaultChecked:
+      javaDefaultCheck.append(check)
+    return self.z.getGui().checkbox(name, javaDefaultCheck, javaOptions)
 
   def show(self, p, **kwargs):
     if hasattr(p, '__name__') and p.__name__ == "matplotlib.pyplot":
@@ -187,7 +203,8 @@ gateway = JavaGateway(client)
 intp = gateway.entry_point
 intp.onPythonScriptInitialized(os.getpid())
 
-z = PyZeppelinContext()
+java_import(gateway.jvm, "org.apache.zeppelin.display.Input")
+z = PyZeppelinContext(intp)
 z._setup_matplotlib()
 
 output = Logger()

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/1972a586/spark/src/main/resources/python/zeppelin_pyspark.py
----------------------------------------------------------------------
diff --git a/spark/src/main/resources/python/zeppelin_pyspark.py b/spark/src/main/resources/python/zeppelin_pyspark.py
index d9c68c2..6c39400 100644
--- a/spark/src/main/resources/python/zeppelin_pyspark.py
+++ b/spark/src/main/resources/python/zeppelin_pyspark.py
@@ -83,6 +83,9 @@ class PyZeppelinContext(dict):
   def get(self, key):
     return self.__getitem__(key)
 
+  def getInterpreterContext(self):
+    return self.z.getInterpreterContext()
+
   def input(self, name, defaultValue=""):
     return self.z.input(name, defaultValue)
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/1972a586/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterContext.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterContext.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterContext.java
index 3f36405..d0db27b 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterContext.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterContext.java
@@ -192,4 +192,8 @@ public class InterpreterContext {
   public void setRemoteWorksController(RemoteWorksController remoteWorksController) {
     this.remoteWorksController = remoteWorksController;
   }
+
+  public InterpreterOutput out() {
+    return out;
+  }
 }