You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by di...@apache.org on 2020/03/20 14:46:23 UTC

[flink] branch release-1.10 updated (3d46037 -> d173d33)

This is an automated email from the ASF dual-hosted git repository.

dianfu pushed a change to branch release-1.10
in repository https://gitbox.apache.org/repos/asf/flink.git.


    from 3d46037  [hotfix][FLINK-16220][json] Fix compile problem in JsonRowSerializationSchemaTest
     new afe7c8e  [FLINK-16538][python][docs] Restructure Python Table API documentation (#11375)
     new d173d33  [FLINK-16691][python][docs] Improve Python UDF documentation to remind users to install PyFlink on the cluster

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 docs/dev/table/config.md                           |   4 -
 docs/dev/table/functions/udfs.md                   | 151 ++-------------------
 docs/dev/table/functions/udfs.zh.md                | 151 ++-------------------
 docs/dev/table/python/dependency_management.md     |  94 +++++++++++++
 docs/dev/table/python/dependency_management.zh.md  |  94 +++++++++++++
 docs/dev/table/python/index.md                     |  35 +++++
 docs/dev/table/python/index.zh.md                  |  35 +++++
 .../table/python/installation.md}                  |  27 +++-
 .../table/python/installation.zh.md}               |  27 +++-
 .../{tuning/index.md => python/python_config.md}   |  15 +-
 .../index.md => python/python_config.zh.md}        |  15 +-
 docs/dev/table/python/python_udfs.md               | 127 +++++++++++++++++
 docs/dev/table/python/python_udfs.zh.md            | 127 +++++++++++++++++
 docs/ops/python_shell.md                           |   7 +-
 docs/ops/python_shell.zh.md                        |   7 +-
 docs/tutorials/python_table_api.md                 |  16 +--
 docs/tutorials/python_table_api.zh.md              |  12 +-
 17 files changed, 602 insertions(+), 342 deletions(-)
 create mode 100644 docs/dev/table/python/dependency_management.md
 create mode 100644 docs/dev/table/python/dependency_management.zh.md
 create mode 100644 docs/dev/table/python/index.md
 create mode 100644 docs/dev/table/python/index.zh.md
 copy docs/{getting-started/tutorials/api_tutorials.zh.md => dev/table/python/installation.md} (52%)
 copy docs/{getting-started/tutorials/api_tutorials.zh.md => dev/table/python/installation.zh.md} (52%)
 copy docs/dev/table/{tuning/index.md => python/python_config.md} (55%)
 copy docs/dev/table/{tuning/index.md => python/python_config.zh.md} (55%)
 create mode 100644 docs/dev/table/python/python_udfs.md
 create mode 100644 docs/dev/table/python/python_udfs.zh.md


[flink] 01/02: [FLINK-16538][python][docs] Restructure Python Table API documentation (#11375)

Posted by di...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dianfu pushed a commit to branch release-1.10
in repository https://gitbox.apache.org/repos/asf/flink.git

commit afe7c8e8346e7c8ecc844d8405619eed1ee588ad
Author: Dian Fu <di...@apache.org>
AuthorDate: Fri Mar 13 14:32:57 2020 +0800

    [FLINK-16538][python][docs] Restructure Python Table API documentation (#11375)
    
    Adds an item "Python Table API" under "Table API & SQL" and move the documentation about Python Table API under it.
---
 docs/dev/table/config.md                          |   4 -
 docs/dev/table/functions/udfs.md                  | 151 ++--------------------
 docs/dev/table/functions/udfs.zh.md               | 151 ++--------------------
 docs/dev/table/python/dependency_management.md    |  94 ++++++++++++++
 docs/dev/table/python/dependency_management.zh.md |  94 ++++++++++++++
 docs/dev/table/python/index.md                    |  35 +++++
 docs/dev/table/python/index.zh.md                 |  35 +++++
 docs/dev/table/python/installation.md             |  44 +++++++
 docs/dev/table/python/installation.zh.md          |  44 +++++++
 docs/dev/table/python/python_config.md            |  32 +++++
 docs/dev/table/python/python_config.zh.md         |  32 +++++
 docs/dev/table/python/python_udfs.md              | 125 ++++++++++++++++++
 docs/dev/table/python/python_udfs.zh.md           | 125 ++++++++++++++++++
 docs/ops/python_shell.md                          |   7 +-
 docs/ops/python_shell.zh.md                       |   7 +-
 docs/tutorials/python_table_api.md                |  16 +--
 docs/tutorials/python_table_api.zh.md             |  12 +-
 17 files changed, 682 insertions(+), 326 deletions(-)

diff --git a/docs/dev/table/config.md b/docs/dev/table/config.md
index a9e9b71..dd312d6 100644
--- a/docs/dev/table/config.md
+++ b/docs/dev/table/config.md
@@ -104,7 +104,3 @@ The following options can be used to tune the performance of the query execution
 The following options can be used to adjust the behavior of the query optimizer to get a better execution plan.
 
 {% include generated/optimizer_config_configuration.html %}
-
-### Python Options
-
-{% include generated/python_configuration.html %}
diff --git a/docs/dev/table/functions/udfs.md b/docs/dev/table/functions/udfs.md
index 523cd61..37cfd04 100644
--- a/docs/dev/table/functions/udfs.md
+++ b/docs/dev/table/functions/udfs.md
@@ -134,37 +134,12 @@ object TimestampModifier extends ScalarFunction {
 </div>
 
 <div data-lang="python" markdown="1">
-<span class="label label-info">Note</span> Python 3.5+ and apache-beam==2.15.0 are required to run the Python scalar function.
+In order to define a Python scalar function, one can extend the base class `ScalarFunction` in `pyflink.table.udf` and implement an evaluation method. The behavior of a Python scalar function is determined by the evaluation method which is named `eval`.
 
-<span class="label label-info">Note</span> By default PyFlink uses the command “python” to run the python udf workers. Before starting cluster, run the following command to confirm that it meets the requirements:
-
-{% highlight bash %}
-$ python --version
-# the version printed here must be 3.5+
-$ python -m pip install apache-beam==2.15.0
-{% endhighlight %}
-
-<span class="label label-info">Note</span> Currently, Python UDF is supported in Blink planner both under streaming and batch mode while is only supported under streaming mode in old planner.
-
-It supports to use both Java/Scala scalar functions and Python scalar functions in Python Table API and SQL. In order to define a Python scalar function, one can extend the base class `ScalarFunction` in `pyflink.table.udf` and implement an evaluation method. The behavior of a Python scalar function is determined by the evaluation method. An evaluation method must be named `eval`. Evaluation method can also support variable arguments, such as `eval(*args)`.
-
-The following example shows how to define your own Java and Python hash code functions, register them in the TableEnvironment, and call them in a query. Note that you can configure your scalar function via a constructor before it is registered:
+The following example shows how to define your own Python hash code function, register it in the TableEnvironment, and call it in a query. Note that you can configure your scalar function via a constructor before it is registered:
 
 {% highlight python %}
-'''
-Java code:
-
-// The Java class must have a public no-argument constructor and can be founded in current Java classloader.
-public class HashCode extends ScalarFunction {
-  private int factor = 12;
-
-  public int eval(String s) {
-      return s.hashCode() * factor;
-  }
-}
-'''
-
-class PyHashCode(ScalarFunction):
+class HashCode(ScalarFunction):
   def __init__(self):
     self.factor = 12
 
@@ -173,128 +148,18 @@ class PyHashCode(ScalarFunction):
 
 table_env = BatchTableEnvironment.create(env)
 
-# register the Java function
-table_env.register_java_function("hashCode", "my.java.function.HashCode")
-
 # register the Python function
-table_env.register_function("py_hash_code", udf(PyHashCode(), DataTypes.BIGINT(), DataTypes.BIGINT()))
+table_env.register_function("hash_code", udf(HashCode(), DataTypes.BIGINT(), DataTypes.BIGINT()))
 
 # use the function in Python Table API
-my_table.select("string, bigint, string.hashCode(), hashCode(string), bigint.py_hash_code(), py_hash_code(bigint)")
+my_table.select("string, bigint, string.hash_code(), hash_code(string)")
 
 # use the function in SQL API
-table_env.sql_query("SELECT string, bigint, hashCode(string), py_hash_code(bigint) FROM MyTable")
-{% endhighlight %}
-
-There are many ways to define a Python scalar function besides extending the base class `ScalarFunction`. The following example shows the different ways to define a Python scalar function which takes two columns of bigint as input parameters and returns the sum of them as the result.
-
-{% highlight python %}
-# option 1: extending the base class `ScalarFunction`
-class Add(ScalarFunction):
-  def eval(self, i, j):
-    return i + j
-
-add = udf(Add(), [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
-
-# option 2: Python function
-@udf(input_types=[DataTypes.BIGINT(), DataTypes.BIGINT()], result_type=DataTypes.BIGINT())
-def add(i, j):
-  return i + j
-
-# option 3: lambda function
-add = udf(lambda i, j: i + j, [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
-
-# option 4: callable function
-class CallableAdd(object):
-  def __call__(self, i, j):
-    return i + j
-
-add = udf(CallableAdd(), [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
-
-# option 5: partial function
-def partial_add(i, j, k):
-  return i + j + k
-
-add = udf(functools.partial(partial_add, k=1), [DataTypes.BIGINT(), DataTypes.BIGINT()],
-          DataTypes.BIGINT())
-
-# register the Python function
-table_env.register_function("add", add)
-# use the function in Python Table API
-my_table.select("add(a, b)")
-{% endhighlight %}
-
-If the python scalar function depends on third-party dependencies, you can specify the dependencies with the following table APIs or through <a href="{{ site.baseurl }}/ops/cli.html#usage">command line</a> directly when submitting the job.
-
-<table class="table table-bordered">
-  <thead>
-    <tr>
-      <th class="text-left" style="width: 20%">APIs</th>
-      <th class="text-left">Description</th>
-    </tr>
-  </thead>
-
-  <tbody>
-    <tr>
-      <td><strong>add_python_file(file_path)</strong></td>
-      <td>
-        <p>Adds python file dependencies which could be python files, python packages or local directories. They will be added to the PYTHONPATH of the python UDF worker.</p>
-{% highlight python %}
-table_env.add_python_file(file_path)
-{% endhighlight %}
-      </td>
-    </tr>
-    <tr>
-      <td><strong>set_python_requirements(requirements_file_path, requirements_cache_dir=None)</strong></td>
-      <td>
-        <p>Specifies a requirements.txt file which defines the third-party dependencies. These dependencies will be installed to a temporary directory and added to the PYTHONPATH of the python UDF worker. For the dependencies which could not be accessed in the cluster, a directory which contains the installation packages of these dependencies could be specified using the parameter "requirements_cached_dir". It will be uploaded to the cluster to support offline installation.</p>
-{% highlight python %}
-# commands executed in shell
-echo numpy==1.16.5 > requirements.txt
-pip download -d cached_dir -r requirements.txt --no-binary :all:
-
-# python code
-table_env.set_python_requirements("requirements.txt", "cached_dir")
-{% endhighlight %}
-        <p>Please make sure the installation packages matches the platform of the cluster and the python version used. These packages will be installed using pip, so also make sure the version of Pip (version >= 7.1.0) and the version of SetupTools (version >= 37.0.0).</p>
-      </td>
-    </tr>
-    <tr>
-      <td><strong>add_python_archive(archive_path, target_dir=None)</strong></td>
-      <td>
-        <p>Adds a python archive file dependency. The file will be extracted to the working directory of python UDF worker. If the parameter "target_dir" is specified, the archive file will be extracted to a directory named "target_dir". Otherwise, the archive file will be extracted to a directory with the same name of the archive file.</p>
-{% highlight python %}
-# command executed in shell
-# assert the relative path of python interpreter is py_env/bin/python
-zip -r py_env.zip py_env
-
-# python code
-table_env.add_python_archive("py_env.zip")
-# or
-table_env.add_python_archive("py_env.zip", "myenv")
-
-# the files contained in the archive file can be accessed in UDF
-def my_udf():
-    with open("myenv/py_env/data/data.txt") as f:
-        ...
-{% endhighlight %}
-        <p>Please make sure the uploaded python environment matches the platform that the cluster is running on. Currently only zip-format is supported. i.e. zip, jar, whl, egg, etc.</p>
-      </td>
-    </tr>
-    <tr>
-      <td><strong>set_python_executable(python_exec)</strong></td>
-      <td>
-        <p>Sets the path of the python interpreter which is used to execute the python udf workers, e.g., "/usr/local/bin/python3".</p>
-{% highlight python %}
-table_env.add_python_archive("py_env.zip")
-table_env.get_config().set_python_executable("py_env.zip/py_env/bin/python")
+table_env.sql_query("SELECT string, bigint, hash_code(bigint) FROM MyTable")
 {% endhighlight %}
-        <p>Please make sure that the specified environment matches the platform that the cluster is running on.</p>
-      </td>
-    </tr>
-  </tbody>
-</table>
 
+There are many ways to define a Python scalar function besides extending the base class `ScalarFunction`.
+Please refer to the [Python Scalar Function]({{ site.baseurl }}/dev/table/python/python_udfs.html#scalar-functions) documentation for more details.
 </div>
 </div>
 
diff --git a/docs/dev/table/functions/udfs.zh.md b/docs/dev/table/functions/udfs.zh.md
index c7cd78e..c35f56a 100644
--- a/docs/dev/table/functions/udfs.zh.md
+++ b/docs/dev/table/functions/udfs.zh.md
@@ -134,37 +134,12 @@ object TimestampModifier extends ScalarFunction {
 </div>
 
 <div data-lang="python" markdown="1">
-<span class="label label-info">Note</span> Python 3.5+ and apache-beam==2.15.0 are required to run the Python scalar function.
+In order to define a Python scalar function, one can extend the base class `ScalarFunction` in `pyflink.table.udf` and implement an evaluation method. The behavior of a Python scalar function is determined by the evaluation method which is named `eval`.
 
-<span class="label label-info">Note</span> By default PyFlink uses the command “python” to run the python udf workers. Before starting cluster, run the following command to confirm that it meets the requirements:
-
-{% highlight bash %}
-$ python --version
-# the version printed here must be 3.5+
-$ python -m pip install apache-beam==2.15.0
-{% endhighlight %}
-
-<span class="label label-info">Note</span> Currently, Python UDF is supported in Blink planner both under streaming and batch mode while is only supported under streaming mode in old planner.
-
-It supports to use both Java/Scala scalar functions and Python scalar functions in Python Table API and SQL. In order to define a Python scalar function, one can extend the base class `ScalarFunction` in `pyflink.table.udf` and implement an evaluation method. The behavior of a Python scalar function is determined by the evaluation method. An evaluation method must be named `eval`. Evaluation method can also support variable arguments, such as `eval(*args)`.
-
-The following example shows how to define your own Java and Python hash code functions, register them in the TableEnvironment, and call them in a query. Note that you can configure your scalar function via a constructor before it is registered:
+The following example shows how to define your own Python hash code function, register it in the TableEnvironment, and call it in a query. Note that you can configure your scalar function via a constructor before it is registered:
 
 {% highlight python %}
-'''
-Java code:
-
-// The Java class must have a public no-argument constructor and can be founded in current Java classloader.
-public class HashCode extends ScalarFunction {
-  private int factor = 12;
-
-  public int eval(String s) {
-      return s.hashCode() * factor;
-  }
-}
-'''
-
-class PyHashCode(ScalarFunction):
+class HashCode(ScalarFunction):
   def __init__(self):
     self.factor = 12
 
@@ -173,128 +148,18 @@ class PyHashCode(ScalarFunction):
 
 table_env = BatchTableEnvironment.create(env)
 
-# register the Java function
-table_env.register_java_function("hashCode", "my.java.function.HashCode")
-
 # register the Python function
-table_env.register_function("py_hash_code", udf(PyHashCode(), DataTypes.BIGINT(), DataTypes.BIGINT()))
+table_env.register_function("hash_code", udf(HashCode(), DataTypes.BIGINT(), DataTypes.BIGINT()))
 
 # use the function in Python Table API
-my_table.select("string, bigint, string.hashCode(), hashCode(string), bigint.py_hash_code(), py_hash_code(bigint)")
+my_table.select("string, bigint, string.hash_code(), hash_code(string)")
 
 # use the function in SQL API
-table_env.sql_query("SELECT string, bigint, hashCode(string), py_hash_code(bigint) FROM MyTable")
-{% endhighlight %}
-
-There are many ways to define a Python scalar function besides extending the base class `ScalarFunction`. The following example shows the different ways to define a Python scalar function which takes two columns of bigint as input parameters and returns the sum of them as the result.
-
-{% highlight python %}
-# option 1: extending the base class `ScalarFunction`
-class Add(ScalarFunction):
-  def eval(self, i, j):
-    return i + j
-
-add = udf(Add(), [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
-
-# option 2: Python function
-@udf(input_types=[DataTypes.BIGINT(), DataTypes.BIGINT()], result_type=DataTypes.BIGINT())
-def add(i, j):
-  return i + j
-
-# option 3: lambda function
-add = udf(lambda i, j: i + j, [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
-
-# option 4: callable function
-class CallableAdd(object):
-  def __call__(self, i, j):
-    return i + j
-
-add = udf(CallableAdd(), [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
-
-# option 5: partial function
-def partial_add(i, j, k):
-  return i + j + k
-
-add = udf(functools.partial(partial_add, k=1), [DataTypes.BIGINT(), DataTypes.BIGINT()],
-          DataTypes.BIGINT())
-
-# register the Python function
-table_env.register_function("add", add)
-# use the function in Python Table API
-my_table.select("add(a, b)")
-{% endhighlight %}
-
-If the python scalar function depends on third-party dependencies, you can specify the dependencies with the following table APIs or through <a href="{{ site.baseurl }}/ops/cli.html#usage">command line</a> directly when submitting the job.
-
-<table class="table table-bordered">
-  <thead>
-    <tr>
-      <th class="text-left" style="width: 20%">APIs</th>
-      <th class="text-left">Description</th>
-    </tr>
-  </thead>
-
-  <tbody>
-    <tr>
-      <td><strong>add_python_file(file_path)</strong></td>
-      <td>
-        <p>Adds python file dependencies which could be python files, python packages or local directories. They will be added to the PYTHONPATH of the python UDF worker.</p>
-{% highlight python %}
-table_env.add_python_file(file_path)
-{% endhighlight %}
-      </td>
-    </tr>
-    <tr>
-      <td><strong>set_python_requirements(requirements_file_path, requirements_cache_dir=None)</strong></td>
-      <td>
-        <p>Specifies a requirements.txt file which defines the third-party dependencies. These dependencies will be installed to a temporary directory and added to the PYTHONPATH of the python UDF worker. For the dependencies which could not be accessed in the cluster, a directory which contains the installation packages of these dependencies could be specified using the parameter "requirements_cached_dir". It will be uploaded to the cluster to support offline installation.</p>
-{% highlight python %}
-# commands executed in shell
-echo numpy==1.16.5 > requirements.txt
-pip download -d cached_dir -r requirements.txt --no-binary :all:
-
-# python code
-table_env.set_python_requirements("requirements.txt", "cached_dir")
-{% endhighlight %}
-        <p>Please make sure the installation packages matches the platform of the cluster and the python version used. These packages will be installed using pip, so also make sure the version of Pip (version >= 7.1.0) and the version of SetupTools (version >= 37.0.0).</p>
-      </td>
-    </tr>
-    <tr>
-      <td><strong>add_python_archive(archive_path, target_dir=None)</strong></td>
-      <td>
-        <p>Adds a python archive file dependency. The file will be extracted to the working directory of python UDF worker. If the parameter "target_dir" is specified, the archive file will be extracted to a directory named "target_dir". Otherwise, the archive file will be extracted to a directory with the same name of the archive file.</p>
-{% highlight python %}
-# command executed in shell
-# assert the relative path of python interpreter is py_env/bin/python
-zip -r py_env.zip py_env
-
-# python code
-table_env.add_python_archive("py_env.zip")
-# or
-table_env.add_python_archive("py_env.zip", "myenv")
-
-# the files contained in the archive file can be accessed in UDF
-def my_udf():
-    with open("myenv/py_env/data/data.txt") as f:
-        ...
-{% endhighlight %}
-        <p>Please make sure the uploaded python environment matches the platform that the cluster is running on. Currently only zip-format is supported. i.e. zip, jar, whl, egg, etc.</p>
-      </td>
-    </tr>
-    <tr>
-      <td><strong>set_python_executable(python_exec)</strong></td>
-      <td>
-        <p>Sets the path of the python interpreter which is used to execute the python udf workers, e.g., "/usr/local/bin/python3".</p>
-{% highlight python %}
-table_env.add_python_archive("py_env.zip")
-table_env.get_config().set_python_executable("py_env.zip/py_env/bin/python")
+table_env.sql_query("SELECT string, bigint, hash_code(bigint) FROM MyTable")
 {% endhighlight %}
-        <p>Please make sure that the specified environment matches the platform that the cluster is running on.</p>
-      </td>
-    </tr>
-  </tbody>
-</table>
 
+There are many ways to define a Python scalar function besides extending the base class `ScalarFunction`.
+Please refer to the [Python Scalar Function]({{ site.baseurl }}/zh/dev/table/python/python_udfs.html#scalar-functions) documentation for more details.
 </div>
 </div>
 
diff --git a/docs/dev/table/python/dependency_management.md b/docs/dev/table/python/dependency_management.md
new file mode 100644
index 0000000..adb8cbe
--- /dev/null
+++ b/docs/dev/table/python/dependency_management.md
@@ -0,0 +1,94 @@
+---
+title: "Dependency Management"
+nav-parent_id: python_tableapi
+nav-pos: 100
+---
+<!--
+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.
+-->
+
+If third-party dependencies are used, you can specify the dependencies with the following Python Table APIs or through <a href="{{ site.baseurl }}/ops/cli.html#usage">command line arguments</a> directly when submitting the job.
+
+<table class="table table-bordered">
+  <thead>
+    <tr>
+      <th class="text-left" style="width: 20%">APIs</th>
+      <th class="text-left">Description</th>
+    </tr>
+  </thead>
+
+  <tbody>
+    <tr>
+      <td><strong>add_python_file(file_path)</strong></td>
+      <td>
+        <p>Adds python file dependencies which could be python files, python packages or local directories. They will be added to the PYTHONPATH of the python UDF worker.</p>
+{% highlight python %}
+table_env.add_python_file(file_path)
+{% endhighlight %}
+      </td>
+    </tr>
+    <tr>
+      <td><strong>set_python_requirements(requirements_file_path, requirements_cache_dir=None)</strong></td>
+      <td>
+        <p>Specifies a requirements.txt file which defines the third-party dependencies. These dependencies will be installed to a temporary directory and added to the PYTHONPATH of the python UDF worker. For the dependencies which could not be accessed in the cluster, a directory which contains the installation packages of these dependencies could be specified using the parameter "requirements_cached_dir". It will be uploaded to the cluster to support offline installation.</p>
+{% highlight python %}
+# commands executed in shell
+echo numpy==1.16.5 > requirements.txt
+pip download -d cached_dir -r requirements.txt --no-binary :all:
+
+# python code
+table_env.set_python_requirements("requirements.txt", "cached_dir")
+{% endhighlight %}
+        <p>Please make sure the installation packages matches the platform of the cluster and the python version used. These packages will be installed using pip, so also make sure the version of Pip (version >= 7.1.0) and the version of SetupTools (version >= 37.0.0).</p>
+      </td>
+    </tr>
+    <tr>
+      <td><strong>add_python_archive(archive_path, target_dir=None)</strong></td>
+      <td>
+        <p>Adds a python archive file dependency. The file will be extracted to the working directory of python UDF worker. If the parameter "target_dir" is specified, the archive file will be extracted to a directory named "target_dir". Otherwise, the archive file will be extracted to a directory with the same name of the archive file.</p>
+{% highlight python %}
+# command executed in shell
+# assert the relative path of python interpreter is py_env/bin/python
+zip -r py_env.zip py_env
+
+# python code
+table_env.add_python_archive("py_env.zip")
+# or
+table_env.add_python_archive("py_env.zip", "myenv")
+
+# the files contained in the archive file can be accessed in UDF
+def my_udf():
+    with open("myenv/py_env/data/data.txt") as f:
+        ...
+{% endhighlight %}
+        <p>Please make sure the uploaded python environment matches the platform that the cluster is running on. Currently only zip-format is supported. i.e. zip, jar, whl, egg, etc.</p>
+      </td>
+    </tr>
+    <tr>
+      <td><strong>set_python_executable(python_exec)</strong></td>
+      <td>
+        <p>Sets the path of the python interpreter which is used to execute the python udf workers, e.g., "/usr/local/bin/python3".</p>
+{% highlight python %}
+table_env.add_python_archive("py_env.zip")
+table_env.get_config().set_python_executable("py_env.zip/py_env/bin/python")
+{% endhighlight %}
+        <p>Please make sure that the specified environment matches the platform that the cluster is running on.</p>
+      </td>
+    </tr>
+  </tbody>
+</table>
diff --git a/docs/dev/table/python/dependency_management.zh.md b/docs/dev/table/python/dependency_management.zh.md
new file mode 100644
index 0000000..5aaf771
--- /dev/null
+++ b/docs/dev/table/python/dependency_management.zh.md
@@ -0,0 +1,94 @@
+---
+title: "依赖管理"
+nav-parent_id: python_tableapi
+nav-pos: 100
+---
+<!--
+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.
+-->
+
+If third-party dependencies are used, you can specify the dependencies with the following Python Table APIs or through <a href="{{ site.baseurl }}/zh/ops/cli.html#usage">command line arguments</a> directly when submitting the job.
+
+<table class="table table-bordered">
+  <thead>
+    <tr>
+      <th class="text-left" style="width: 20%">APIs</th>
+      <th class="text-left">Description</th>
+    </tr>
+  </thead>
+
+  <tbody>
+    <tr>
+      <td><strong>add_python_file(file_path)</strong></td>
+      <td>
+        <p>Adds python file dependencies which could be python files, python packages or local directories. They will be added to the PYTHONPATH of the python UDF worker.</p>
+{% highlight python %}
+table_env.add_python_file(file_path)
+{% endhighlight %}
+      </td>
+    </tr>
+    <tr>
+      <td><strong>set_python_requirements(requirements_file_path, requirements_cache_dir=None)</strong></td>
+      <td>
+        <p>Specifies a requirements.txt file which defines the third-party dependencies. These dependencies will be installed to a temporary directory and added to the PYTHONPATH of the python UDF worker. For the dependencies which could not be accessed in the cluster, a directory which contains the installation packages of these dependencies could be specified using the parameter "requirements_cached_dir". It will be uploaded to the cluster to support offline installation.</p>
+{% highlight python %}
+# commands executed in shell
+echo numpy==1.16.5 > requirements.txt
+pip download -d cached_dir -r requirements.txt --no-binary :all:
+
+# python code
+table_env.set_python_requirements("requirements.txt", "cached_dir")
+{% endhighlight %}
+        <p>Please make sure the installation packages matches the platform of the cluster and the python version used. These packages will be installed using pip, so also make sure the version of Pip (version >= 7.1.0) and the version of SetupTools (version >= 37.0.0).</p>
+      </td>
+    </tr>
+    <tr>
+      <td><strong>add_python_archive(archive_path, target_dir=None)</strong></td>
+      <td>
+        <p>Adds a python archive file dependency. The file will be extracted to the working directory of python UDF worker. If the parameter "target_dir" is specified, the archive file will be extracted to a directory named "target_dir". Otherwise, the archive file will be extracted to a directory with the same name of the archive file.</p>
+{% highlight python %}
+# command executed in shell
+# assert the relative path of python interpreter is py_env/bin/python
+zip -r py_env.zip py_env
+
+# python code
+table_env.add_python_archive("py_env.zip")
+# or
+table_env.add_python_archive("py_env.zip", "myenv")
+
+# the files contained in the archive file can be accessed in UDF
+def my_udf():
+    with open("myenv/py_env/data/data.txt") as f:
+        ...
+{% endhighlight %}
+        <p>Please make sure the uploaded python environment matches the platform that the cluster is running on. Currently only zip-format is supported. i.e. zip, jar, whl, egg, etc.</p>
+      </td>
+    </tr>
+    <tr>
+      <td><strong>set_python_executable(python_exec)</strong></td>
+      <td>
+        <p>Sets the path of the python interpreter which is used to execute the python udf workers, e.g., "/usr/local/bin/python3".</p>
+{% highlight python %}
+table_env.add_python_archive("py_env.zip")
+table_env.get_config().set_python_executable("py_env.zip/py_env/bin/python")
+{% endhighlight %}
+        <p>Please make sure that the specified environment matches the platform that the cluster is running on.</p>
+      </td>
+    </tr>
+  </tbody>
+</table>
diff --git a/docs/dev/table/python/index.md b/docs/dev/table/python/index.md
new file mode 100644
index 0000000..4163374
--- /dev/null
+++ b/docs/dev/table/python/index.md
@@ -0,0 +1,35 @@
+---
+title: "Python Table API"
+nav-id: python_tableapi
+nav-parent_id: tableapi
+nav-pos: 100
+nav-show_overview: true
+---
+<!--
+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.
+-->
+
+Python Table API allows users to develop [Table API]({{ site.baseurl }}/dev/table/tableApi.html) programs using the Python language.
+Apache Flink has provided Python Table API support since 1.9.0.
+
+## Where to go next?
+
+- [Installation]({{ site.baseurl }}/dev/table/python/installation.html): Introduction of how to set up the Python Table API execution environment.
+- [User-defined Functions]({{ site.baseurl }}/dev/table/python/python_udfs.html): Explanation of how to define Python user-defined functions.
+- [Dependency Management]({{ site.baseurl }}/dev/table/python/dependency_management.html): Specification of how to use third-part dependencies in a Python Table API program.
+- [Configuration]({{ site.baseurl }}/dev/table/python/python_config.html): Description of the config options available for Python Table API programs.
diff --git a/docs/dev/table/python/index.zh.md b/docs/dev/table/python/index.zh.md
new file mode 100644
index 0000000..fa1323c
--- /dev/null
+++ b/docs/dev/table/python/index.zh.md
@@ -0,0 +1,35 @@
+---
+title: "Python Table API"
+nav-id: python_tableapi
+nav-parent_id: tableapi
+nav-pos: 100
+nav-show_overview: true
+---
+<!--
+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.
+-->
+
+Python Table API allows users to develop [Table API]({{ site.baseurl }}/zh/dev/table/tableApi.html) programs using the Python language.
+Apache Flink has provided Python Table API support since 1.9.0.
+
+## Where to go next?
+
+- [环境安装]({{ site.baseurl }}/zh/dev/table/python/installation.html): Introduction of how to set up the Python Table API execution environment.
+- [自定义函数]({{ site.baseurl }}/zh/dev/table/python/python_udfs.html): Explanation of how to define Python user-defined functions.
+- [依赖管理]({{ site.baseurl }}/zh/dev/table/python/dependency_management.html): Specification of how to use third-part dependencies in a Python Table API program.
+- [配置]({{ site.baseurl }}/zh/dev/table/python/python_config.html): Description of the config options available for Python Table API programs.
diff --git a/docs/dev/table/python/installation.md b/docs/dev/table/python/installation.md
new file mode 100644
index 0000000..0dffb77
--- /dev/null
+++ b/docs/dev/table/python/installation.md
@@ -0,0 +1,44 @@
+---
+title: "Installation"
+nav-parent_id: python_tableapi
+nav-pos: 10
+---
+<!--
+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.
+-->
+
+* This will be replaced by the TOC
+{:toc}
+
+## Environment Requirements
+<span class="label label-info">Note</span> Python 3.5+ is required for PyFlink. Please run the following command to make sure that it meets the requirements:
+
+{% highlight bash %}
+$ python --version
+# the version printed here must be 3.5+
+{% endhighlight %}
+
+## Installation of PyFlink
+
+PyFlink has already been deployed to PyPi and can be installed as following:
+
+{% highlight bash %}
+$ python -m pip install apache-flink
+{% endhighlight %}
+
+You can also build PyFlink from source by following the [development guide]({{ site.baseurl }}/flinkDev/building.html#build-pyflink).
diff --git a/docs/dev/table/python/installation.zh.md b/docs/dev/table/python/installation.zh.md
new file mode 100644
index 0000000..e07660a
--- /dev/null
+++ b/docs/dev/table/python/installation.zh.md
@@ -0,0 +1,44 @@
+---
+title: "环境安装"
+nav-parent_id: python_tableapi
+nav-pos: 10
+---
+<!--
+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.
+-->
+
+* This will be replaced by the TOC
+{:toc}
+
+## Environment Requirements
+<span class="label label-info">Note</span> Python 3.5+ is required for PyFlink. Please run the following command to make sure that it meets the requirements:
+
+{% highlight bash %}
+$ python --version
+# the version printed here must be 3.5+
+{% endhighlight %}
+
+## Installation of PyFlink
+
+PyFlink has already been deployed to PyPi and can be installed as following:
+
+{% highlight bash %}
+$ python -m pip install apache-flink
+{% endhighlight %}
+
+You can also build PyFlink from source by following the [development guide]({{ site.baseurl }}/zh/flinkDev/building.html#build-pyflink).
diff --git a/docs/dev/table/python/python_config.md b/docs/dev/table/python/python_config.md
new file mode 100644
index 0000000..e25fbf5
--- /dev/null
+++ b/docs/dev/table/python/python_config.md
@@ -0,0 +1,32 @@
+---
+title: "Configuration"
+nav-parent_id: python_tableapi
+nav-pos: 120
+---
+<!--
+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.
+-->
+
+Depending on the requirements of a Python Table API program, it might be necessary to adjust certain parameters for optimization.
+All the config options available for Java/Scala Table API program could also be used in the Python Table API program.
+You could refer to the [Table API Configuration]({{ site.baseurl }}/dev/table/config.html) for more details on all the available config options for Java/Scala Table API programs.
+It has also provided examples on how to set the config options in a Table API program.
+
+## Python Options
+
+{% include generated/python_configuration.html %}
diff --git a/docs/dev/table/python/python_config.zh.md b/docs/dev/table/python/python_config.zh.md
new file mode 100644
index 0000000..fa4f59d
--- /dev/null
+++ b/docs/dev/table/python/python_config.zh.md
@@ -0,0 +1,32 @@
+---
+title: "配置"
+nav-parent_id: python_tableapi
+nav-pos: 120
+---
+<!--
+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.
+-->
+
+Depending on the requirements of a Python Table API program, it might be necessary to adjust certain parameters for optimization.
+All the config options available for Java/Scala Table API program could also be used in the Python Table API program.
+You could refer to the [Table API Configuration]({{ site.baseurl }}/zh/dev/table/config.html) for more details on all the available config options for Java/Scala Table API programs.
+It has also provided examples on how to set the config options in a Table API program.
+
+## Python Options
+
+{% include generated/python_configuration.html %}
diff --git a/docs/dev/table/python/python_udfs.md b/docs/dev/table/python/python_udfs.md
new file mode 100644
index 0000000..44a30ff
--- /dev/null
+++ b/docs/dev/table/python/python_udfs.md
@@ -0,0 +1,125 @@
+---
+title: "User-defined Functions"
+nav-parent_id: python_tableapi
+nav-pos: 20
+---
+<!--
+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.
+-->
+
+User-defined functions are important features, because they significantly extend the expressiveness of Python Table API programs.
+
+* This will be replaced by the TOC
+{:toc}
+
+## Scalar Functions
+It supports to use Python scalar functions in Python Table API programs. In order to define a Python scalar function,
+one can extend the base class `ScalarFunction` in `pyflink.table.udf` and implement an evaluation method.
+The behavior of a Python scalar function is defined by the evaluation method which is named `eval`.
+The evaluation method can support variable arguments, such as `eval(*args)`.
+
+The following example shows how to define your own Python hash code function, register it in the TableEnvironment, and call it in a query.
+Note that you can configure your scalar function via a constructor before it is registered:
+
+{% highlight python %}
+class HashCode(ScalarFunction):
+  def __init__(self):
+    self.factor = 12
+
+  def eval(self, s):
+    return hash(s) * self.factor
+
+table_env = BatchTableEnvironment.create(env)
+
+# register the Python function
+table_env.register_function("hash_code", udf(HashCode(), DataTypes.BIGINT(), DataTypes.BIGINT()))
+
+# use the Python function in Python Table API
+my_table.select("string, bigint, bigint.hash_code(), hash_code(bigint)")
+
+# use the Python function in SQL API
+table_env.sql_query("SELECT string, bigint, hash_code(bigint) FROM MyTable")
+{% endhighlight %}
+
+It also supports to use Java/Scala scalar functions in Python Table API programs.
+
+{% highlight python %}
+'''
+Java code:
+
+// The Java class must have a public no-argument constructor and can be founded in current Java classloader.
+public class HashCode extends ScalarFunction {
+  private int factor = 12;
+
+  public int eval(String s) {
+      return s.hashCode() * factor;
+  }
+}
+'''
+
+table_env = BatchTableEnvironment.create(env)
+
+# register the Java function
+table_env.register_java_function("hash_code", "my.java.function.HashCode")
+
+# use the Java function in Python Table API
+my_table.select("string.hash_code(), hash_code(string)")
+
+# use the Java function in SQL API
+table_env.sql_query("SELECT string, bigint, hash_code(string) FROM MyTable")
+{% endhighlight %}
+
+There are many ways to define a Python scalar function besides extending the base class `ScalarFunction`.
+The following examples show the different ways to define a Python scalar function which takes two columns of
+bigint as the input parameters and returns the sum of them as the result.
+
+{% highlight python %}
+# option 1: extending the base class `ScalarFunction`
+class Add(ScalarFunction):
+  def eval(self, i, j):
+    return i + j
+
+add = udf(Add(), [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
+
+# option 2: Python function
+@udf(input_types=[DataTypes.BIGINT(), DataTypes.BIGINT()], result_type=DataTypes.BIGINT())
+def add(i, j):
+  return i + j
+
+# option 3: lambda function
+add = udf(lambda i, j: i + j, [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
+
+# option 4: callable function
+class CallableAdd(object):
+  def __call__(self, i, j):
+    return i + j
+
+add = udf(CallableAdd(), [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
+
+# option 5: partial function
+def partial_add(i, j, k):
+  return i + j + k
+
+add = udf(functools.partial(partial_add, k=1), [DataTypes.BIGINT(), DataTypes.BIGINT()],
+          DataTypes.BIGINT())
+
+# register the Python function
+table_env.register_function("add", add)
+# use the function in Python Table API
+my_table.select("add(a, b)")
+{% endhighlight %}
diff --git a/docs/dev/table/python/python_udfs.zh.md b/docs/dev/table/python/python_udfs.zh.md
new file mode 100644
index 0000000..7acba1f
--- /dev/null
+++ b/docs/dev/table/python/python_udfs.zh.md
@@ -0,0 +1,125 @@
+---
+title: "自定义函数"
+nav-parent_id: python_tableapi
+nav-pos: 20
+---
+<!--
+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.
+-->
+
+User-defined functions are important features, because they significantly extend the expressiveness of Python Table API programs.
+
+* This will be replaced by the TOC
+{:toc}
+
+## Scalar Functions
+It supports to use Python scalar functions in Python Table API programs. In order to define a Python scalar function,
+one can extend the base class `ScalarFunction` in `pyflink.table.udf` and implement an evaluation method.
+The behavior of a Python scalar function is defined by the evaluation method which is named `eval`.
+The evaluation method can support variable arguments, such as `eval(*args)`.
+
+The following example shows how to define your own Python hash code function, register it in the TableEnvironment, and call it in a query.
+Note that you can configure your scalar function via a constructor before it is registered:
+
+{% highlight python %}
+class HashCode(ScalarFunction):
+  def __init__(self):
+    self.factor = 12
+
+  def eval(self, s):
+    return hash(s) * self.factor
+
+table_env = BatchTableEnvironment.create(env)
+
+# register the Python function
+table_env.register_function("hash_code", udf(HashCode(), DataTypes.BIGINT(), DataTypes.BIGINT()))
+
+# use the Python function in Python Table API
+my_table.select("string, bigint, bigint.hash_code(), hash_code(bigint)")
+
+# use the Python function in SQL API
+table_env.sql_query("SELECT string, bigint, hash_code(bigint) FROM MyTable")
+{% endhighlight %}
+
+It also supports to use Java/Scala scalar functions in Python Table API programs.
+
+{% highlight python %}
+'''
+Java code:
+
+// The Java class must have a public no-argument constructor and can be founded in current Java classloader.
+public class HashCode extends ScalarFunction {
+  private int factor = 12;
+
+  public int eval(String s) {
+      return s.hashCode() * factor;
+  }
+}
+'''
+
+table_env = BatchTableEnvironment.create(env)
+
+# register the Java function
+table_env.register_java_function("hash_code", "my.java.function.HashCode")
+
+# use the Java function in Python Table API
+my_table.select("string.hash_code(), hash_code(string)")
+
+# use the Java function in SQL API
+table_env.sql_query("SELECT string, bigint, hash_code(string) FROM MyTable")
+{% endhighlight %}
+
+There are many ways to define a Python scalar function besides extending the base class `ScalarFunction`.
+The following examples show the different ways to define a Python scalar function which takes two columns of
+bigint as the input parameters and returns the sum of them as the result.
+
+{% highlight python %}
+# option 1: extending the base class `ScalarFunction`
+class Add(ScalarFunction):
+  def eval(self, i, j):
+    return i + j
+
+add = udf(Add(), [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
+
+# option 2: Python function
+@udf(input_types=[DataTypes.BIGINT(), DataTypes.BIGINT()], result_type=DataTypes.BIGINT())
+def add(i, j):
+  return i + j
+
+# option 3: lambda function
+add = udf(lambda i, j: i + j, [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
+
+# option 4: callable function
+class CallableAdd(object):
+  def __call__(self, i, j):
+    return i + j
+
+add = udf(CallableAdd(), [DataTypes.BIGINT(), DataTypes.BIGINT()], DataTypes.BIGINT())
+
+# option 5: partial function
+def partial_add(i, j, k):
+  return i + j + k
+
+add = udf(functools.partial(partial_add, k=1), [DataTypes.BIGINT(), DataTypes.BIGINT()],
+          DataTypes.BIGINT())
+
+# register the Python function
+table_env.register_function("add", add)
+# use the function in Python Table API
+my_table.select("add(a, b)")
+{% endhighlight %}
diff --git a/docs/ops/python_shell.md b/docs/ops/python_shell.md
index f561a1c..259d3d2 100644
--- a/docs/ops/python_shell.md
+++ b/docs/ops/python_shell.md
@@ -27,12 +27,7 @@ It can be used in a local setup as well as in a cluster setup.
 See the [local setup page](../getting-started/tutorials/local_setup.html) for more information about how to setup a local Flink.
 You can also [build a local setup from source](../flinkDev/building.html).
 
-<span class="label label-info">Note</span> The Python Shell will run the command “python”. Please run the following command to confirm that the command “python” in current environment points to Python 3.5+:
-
-{% highlight bash %}
-$ python --version
-# the version printed here must be 3.5+
-{% endhighlight %}
+<span class="label label-info">Note</span> The Python Shell will run the command “python”. <span class="label label-info">Note</span> The Python Shell will run the command “python”. Please refer to the Python Table API [installation guide]({{ site.baseurl }}/dev/table/python/installation.html) on how to set up the Python execution environments.
 
 To use the shell with an integrated Flink cluster, you can simply install PyFlink with PyPi and execute the shell directly:
 
diff --git a/docs/ops/python_shell.zh.md b/docs/ops/python_shell.zh.md
index 0150e30..cae6a1d 100644
--- a/docs/ops/python_shell.zh.md
+++ b/docs/ops/python_shell.zh.md
@@ -27,12 +27,7 @@ Flink附带了一个集成的交互式Python Shell。
 本地安装Flink,请看[本地安装](../getting-started/tutorials/local_setup.html)页面。
 您也可以从源码安装Flink,请看[从源码构建 Flink](../flinkDev/building.html)页面。
 
-<span class="label label-info">注意</span> Python Shell会调用“python”命令。请执行以下命令以确认当前环境下的指令“python”指向Python 3.5及以上版本:
-
-{% highlight bash %}
-$ python --version
-# the version printed here must be 3.5+
-{% endhighlight %}
+<span class="label label-info">注意</span> Python Shell会调用“python”命令。关于Python执行环境的要求,请参考Python Table API[环境安装]({{ site.baseurl }}/dev/dev/table/python/installation.html)。
 
 你可以通过PyPi安装PyFlink,然后使用Python Shell:
 
diff --git a/docs/tutorials/python_table_api.md b/docs/tutorials/python_table_api.md
index b7f0d1d..91fadb7 100644
--- a/docs/tutorials/python_table_api.md
+++ b/docs/tutorials/python_table_api.md
@@ -25,26 +25,14 @@ under the License.
 
 This walkthrough will quickly get you started building a pure Python Flink project.
 
-<span class="label label-info">Note</span> Python 3.5 or higher is required to run PyFlink. Run the following command to confirm that the command “python” in current environment points to Python 3.5+:
-
-{% highlight bash %}
-$ python --version
-# the version printed here must be 3.5+
-{% endhighlight %}
+Please refer to the Python Table API [installation guide]({{ site.baseurl }}/dev/table/python/installation.html) on how to set up the Python execution environments.
 
 * This will be replaced by the TOC
 {:toc}
 
 ## Setting up a Python Project
 
-You can begin by creating a Python project and installing the PyFlink package.
-PyFlink is available via PyPi and can be easily installed using `pip`.
-
-{% highlight bash %}
-$ python -m pip install apache-flink
-{% endhighlight %}
-
-You can also build PyFlink from source by following the [development guide]({{ site.baseurl }}/flinkDev/building.html#build-pyflink).
+You can begin by creating a Python project and installing the PyFlink package following the [installation guide]({{ site.baseurl }}/dev/table/python/installation.html#installation-of-pyflink).
 
 ## Writing a Flink Python Table API Program
 
diff --git a/docs/tutorials/python_table_api.zh.md b/docs/tutorials/python_table_api.zh.md
index 89be567..9a5d586 100644
--- a/docs/tutorials/python_table_api.zh.md
+++ b/docs/tutorials/python_table_api.zh.md
@@ -28,19 +28,11 @@ under the License.
 
 在该教程中,我们会从零开始,介绍如何创建一个Flink Python项目及运行Python Table API程序。
 
-<span class="label label-info">注意</span> PyFlink的运行需要Python 3.5及以上版本。
-
-执行以下命令以确认当前环境下的指令“python”指向Python 3.5及以上版本:
-
-{% highlight bash %}
-$ python --version
-# the version printed here must be 3.5+
-{% endhighlight %}
+关于Python执行环境的要求,请参考Python Table API[环境安装]({{ site.baseurl }}/dev/dev/table/python/installation.html)。
 
 ## 创建一个Python Table API项目
 
-首先,使用您最熟悉的IDE创建一个Python项目。之后执行命令`python -m pip install apache-flink`从PyPI下载安装PyFlink包。
-如果您想从源码安装,请参考[构建PyFlink]({{ site.baseurl }}/zh/flinkDev/building.html#build-pyflink)了解详细信息。
+首先,使用您最熟悉的IDE创建一个Python项目,然后安装PyFlink包,请参考[PyFlink安装指南]({{ site.baseurl }}/zh/dev/table/python/installation.html#installation-of-pyflink)了解详细信息。
 
 ## 编写一个Flink Python Table API程序
 


[flink] 02/02: [FLINK-16691][python][docs] Improve Python UDF documentation to remind users to install PyFlink on the cluster

Posted by di...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dianfu pushed a commit to branch release-1.10
in repository https://gitbox.apache.org/repos/asf/flink.git

commit d173d337cda85084bb7890054bfe04cecf1f9694
Author: huangxingbo <hx...@gmail.com>
AuthorDate: Fri Mar 20 17:41:38 2020 +0800

    [FLINK-16691][python][docs] Improve Python UDF documentation to remind users to install PyFlink on the cluster
    
    This closes #11462.
---
 docs/dev/table/python/python_udfs.md    | 2 ++
 docs/dev/table/python/python_udfs.zh.md | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/docs/dev/table/python/python_udfs.md b/docs/dev/table/python/python_udfs.md
index 44a30ff..fd4a99d 100644
--- a/docs/dev/table/python/python_udfs.md
+++ b/docs/dev/table/python/python_udfs.md
@@ -24,6 +24,8 @@ under the License.
 
 User-defined functions are important features, because they significantly extend the expressiveness of Python Table API programs.
 
+**NOTE:** Python UDF execution requires Python3.5+ with PyFlink installed. It's required on both the client side and the cluster side. 
+
 * This will be replaced by the TOC
 {:toc}
 
diff --git a/docs/dev/table/python/python_udfs.zh.md b/docs/dev/table/python/python_udfs.zh.md
index 7acba1f..11f896c 100644
--- a/docs/dev/table/python/python_udfs.zh.md
+++ b/docs/dev/table/python/python_udfs.zh.md
@@ -24,6 +24,8 @@ under the License.
 
 User-defined functions are important features, because they significantly extend the expressiveness of Python Table API programs.
 
+**NOTE:** Python UDF execution requires Python3.5+ with PyFlink installed. It's required on both the client side and the cluster side.
+
 * This will be replaced by the TOC
 {:toc}