packaging a python script

Paul

  ·  1 min read

The below script creates a debian package “hello_0.1-1_amd64.deb”, from the Python script ‘hello.py’.

First, all dependencies listed in requirements.txt are installed into a fresh virtual environment (releaseenv). The required program ‘pyinstaller’ is also pip-installed.

#!/bin/sh
NAME="hello"
SCRIPT_NAME="hello.py"
VERSION="0.1"
RELEASE="1"

rm -rf ./build ./dist ./releaseenv
rm -f ${NAME}.spec
rm -rf ./*.deb

python3 -m venv releaseenv
. releaseenv/bin/activate
pip3 install -r requirements.txt
pip3 install pyinstaller

Next, ‘pyinstaller’ generates a single binary from the Python script ‘hello.py’. The generated binary (dist/hello) can be tested/run locally prior to packaging:

#!/bin/sh
pyinstaller -y --clean --name ${NAME} --log-level DEBUG --onefile --paths releaseenv/lib/python3.8/site-packages/ ${SCRIPT_NAME}

Finally, create a basic Debian package:

#!/bin/sh
MAIN_FOLDER="${NAME}_${VERSION}-${RELEASE}_amd64"
DEBIAN_FOLDER="${MAIN_FOLDER}/DEBIAN"
EXEC_FOLDER="${MAIN_FOLDER}/usr/local/bin"

CONTROL_FILE="${DEBIAN_FOLDER}/control"

mkdir -p ${MAIN_FOLDER}
mkdir -p ${DEBIAN_FOLDER}
mkdir -p ${EXEC_FOLDER}
touch ${CONTROL_FILE}

echo "Package: ${NAME}" > ${CONTROL_FILE}
echo "Version: ${VERSION}" >> ${CONTROL_FILE}
echo "Architecture: amd64" >> ${CONTROL_FILE}
echo "Maintainer: Paul Malcolm <paul.malcolm@protonmail.com>" >> ${CONTROL_FILE}
echo "Description: Brief description of the application" >> ${CONTROL_FILE}

cp dist/${NAME} ${EXEC_FOLDER}

dpkg-deb --build --root-owner-group ${MAIN_FOLDER}

rm -rf ./build ./dist ./releaseenv
rm -f ${NAME}.spec
rm -rf ${MAIN_FOLDER}

The final output is a Debian package (.deb), which can be easily published, and installed using ‘apt’ or ‘dpkg’:

sudo apt install {NAME}_${VERSION}-${RELEASE}_amd64.deb
sudo dpkg -i {NAME}_${VERSION}-${RELEASE}_amd64.deb