blob: 91a324ecd567e3818d4149c6cbcc6ef993fc5c97 [file] [log] [blame] [view]
---
id: functions-package-python
title: Package Python Functions
sidebar_label: "Package Python Functions"
description: Learn to package Python functions in Pulsar.
---
Python functions support the following three packaging formats:
## One Python file
To package a Python function into **one Python file**, complete the following steps.
1. Write a Python function.
```python
from pulsar import Function # import the Function module from Pulsar
# The classic ExclamationFunction that appends an exclamation at the end
# of the input
class ExclamationFunction(Function):
def __init__(self):
pass
def process(self, input, context):
return input + '!'
```
In this example, when you write a Python function, you need to inherit the Function class and implement the `process()` method.
`process()` mainly has two parameters:
- `input` represents your input.
- `context` represents an interface exposed by the Pulsar Function. You can get the attributes in the Python function based on the provided context object.
2. Install a Python client. The implementation of a Python function depends on the Python client.
```bash
pip install pulsar-client==2.10.0
```
And install protobuf tools to generate the proto files:
```bash
pip install 'protobuf==3.20.*'
```
3. Copy the Python function file to the Pulsar image.
```bash
docker exec -it [CONTAINER ID] /bin/bash
docker cp <path of Python function file> CONTAINER ID:/pulsar
```
4. Run the Python function using the following command.
```bash
./bin/pulsar-admin functions localrun \
--classname <Python Function file name>.<Python Function class name> \
--py <absolute path of Python Function file> \
--inputs persistent://public/default/my-topic-1 \
--output persistent://public/default/test-1 \
--tenant public \
--namespace default \
--name PythonFunction
```
The following log indicates that the Python function starts successfully.
```text
...
07:55:03.724 [main] INFO org.apache.pulsar.functions.runtime.ProcessRuntime - Started process successfully
...
```
## ZIP file
To package a Python function into a **ZIP file**, complete the following steps.
1. Prepare the ZIP file.
```text
Assuming the zip file is named as `func.zip`, unzip the `func.zip` folder:
"func/src"
"func/requirements.txt"
"func/deps"
```
Take the [exclamation.zip](https://github.com/apache/pulsar/tree/master/tests/docker-images/latest-version-image/python-examples) file as an example. The internal structure of the example is as follows.
```text
.
├── deps
│ └── sh-1.12.14-py2.py3-none-any.whl
└── src
└── exclamation.py
```
2. Copy the ZIP file to the Pulsar image.
```bash
docker exec -it [CONTAINER ID] /bin/bash
docker cp <path of ZIP file> CONTAINER ID:/pulsar
```
3. Run the Python function using the following command.
```shell
./bin/pulsar-admin functions localrun \
--classname exclamation \
--py <absolute path of ZIP file> \
--inputs persistent://public/default/in-topic \
--output persistent://public/default/out-topic \
--tenant public \
--namespace default \
--name PythonFunction
```
The following log indicates that the Python function starts successfully.
```text
...
07:55:03.724 [main] INFO org.apache.pulsar.functions.runtime.ProcessRuntime - Started process successfully
...
```
## PIP
:::note
The PIP method is only supported in Kubernetes runtime.
:::
To package a Python function with **PIP**, complete the following steps.
1. Configure the `functions_worker.yml` file.
```shell
#### Kubernetes Runtime ####
installUserCodeDependencies: true
```
2. Write your Python Function.
```python
from pulsar import Function
import js2xml
# The classic ExclamationFunction that appends an exclamation at the end
# of the input
class ExclamationFunction(Function):
def __init__(self):
pass
def process(self, input, context):
# add your logic
return input + '!'
```
You can introduce additional dependencies. When Python functions detect that the file currently used is `whl` and the `installUserCodeDependencies` parameter is specified, the system uses the `pip install` command to install the dependencies required in Python functions.
3. Generate the `whl` file.
```shell
cd $PULSAR_HOME/pulsar-functions/scripts/python
chmod +x generate.sh
./generate.sh <path of your Python Function> <path of the whl output dir> <the version of whl>
# e.g: ./generate.sh /path/to/python /path/to/python/output 1.0.0
```
The output is written in `/path/to/python/output`:
```text
-rw-r--r-- 1 root staff 1.8K 8 27 14:29 pulsarfunction-1.0.0-py2-none-any.whl
-rw-r--r-- 1 root staff 1.4K 8 27 14:29 pulsarfunction-1.0.0.tar.gz
-rw-r--r-- 1 root staff 0B 8 27 14:29 pulsarfunction.whl
```