Here we create a library mylib.py, an entrance file app.py. Then compile library to .so file to protect its source codes. Finally run app.py as a normal python script.
$ pip install pandas numpy cython
# or install with: conda install -c anaconda cython ...
$ cat << EOF > mylib.py
import pandas as pd
import numpy as np
def col_max(inp: pd.DataFrame) -> pd.Series:
return np.max(inp)
EOF
$ cat << EOF > app.py
import pandas as pd
from mylib import col_max
data = pd.DataFrame({'col1': [1,2,3], 'col2': [11,12,13]})
print(col_max(data))
EOF
$ cythonize -a -i mylib.py
$ mv mylib.cpython-37m-x86_64-linux-gnu.so mylib.so
$ rm mylib.py
$ python app.py
col1 3
col2 13
dtype: int64
This method doesn't deal with dependent Python packages, here are numpy and pandas. You have to install them manually.
You can deliver .so files to other hosts with same CPU architecture. For example, you can compile Python scripts on a Ubuntu host, then run them on a CentOS host.