Packaging Python Projects

Posted on

This tutorial demonstrates how to package a simple Python project. It will show you how to create file and folder structure for a python package
*how to build the package, and how to upload it to the Python Package Index.

Sensor Database Project

This tutorial will create project named RaspberryPi3B_Sensors_pkg With the following file structure:

RaspberryPi3B_Sensors
|---SetupFiles
    |---__init__.py 

The commands must be run from the Top Level Folder: “~/RaspberryPi3B_Sensors/”
For each Folder the file “~/__ init __.py” is required to import the directory as a package (even if file is empty)

Creating Package Files

The folders and files that make up the package will be in the Top Level Folder

RaspberryPi3B_Sensors
|--- LICENSE
|--- README.md
|--  SetupFiles
     |---__init__.py
|--  tests
|--- setup.py

Creating setup.py

The build script will contain and run setuptools module which establishes information about the package created. User name was added to package name to allow forking and customizing different versions.

See Packaging and distributing projects for more details on setup().

Creating README.md

The read me should include all details about the package, This is loaded into setup().description for this package. The file should describe the package and include as much details as needed to explain package. Example: Contact, URL Links, Overview, Basic Usage, Example descriptions, Change history… etc.

A Pyhton Project To automate Sensor Kit use on Raspberry Pi
Visit VG-1 Raspberry Pi Blog

Contact
Gil Medel doubleecpu@outlook.com
Overview:
The Project setsup Raspberry Pi to read sensor data
Sensors are set up and read in python and data is stored to MariaDB (MySQL) and data is Displayed in WordPress website
Basic Usage:
Examples:
What's New For Version 0.0.1
9/18/2020
Setup as Python Package formatting, Set up Test Driven Development Files, Synced To GitHub

Creating License for package

To inform users that install the package the terms under which they can use the package. A great resource for guidance on picking a license https://choosealicense.com/
Example: Using an MIT License

Copyright (c) 2019 Gilbert Medel

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Generate Distribution Archives

To generate distribution packages for a package make sure you have the latest versions of setuptools and wheel installed. This will create archives that are uploaded to the Package Index and can then be installed using pip command.

python3 -m pip install --user --upgrade setuptools wheel

The command should output text on the command line and once completed should generate two files in the dist directory:
dist/
|— RaspberryPi3B_Sensors_doubleecpu-0.0.1-py3-none-any.whl
|— RaspberryPi3B_Sensors_doubleecpu-0.0.1.tar.gz

The tar.gz file is a Source Archive whereas the .whl file is a Built Distribution. Newer pip versions preferentially install built distributions, but will fall back to source archives if needed. It is Required to upload a source archive and provide built archives for the platforms the project is compatible with. For this example package is compatible with Python on any Raspbian Linux so that built distribution is needed along with any other version that should be compatible.

Uploading the distribution archives

After registering for an account on Test PyPI (a separate instance of the package index for testing before uploading to the real index), URL https://test.pypi.org/account/register/, complete the steps on that page and verify email address before trying to upload any packages.
Using a PyPI API token allows for securely uploading your package. NEW API Tokens can be created and downloaded https://test.pypi.org/manage/account/#api-tokens
*don’t limit its scope to a particular project, since you are creating a new project.

copy and save the token from the page as it will not be available after closing page

Install Twine to upload package distribution archives

python3 -m pip install --user --upgrade twine

To upload all of the distribution archives in the dist/ folder:

python3 -m twine upload --repository testpypi dist/*

When prompted enter username and password.
For the username, use __ token __.
For the password, use the token value, including the pypi- prefix.

After the command completes, the output should look similar to this:

Uploading distributions to https://test.pypi.org/legacy/ Enter your username: [your username] Enter your password: Uploading RaspberryPi3B_Sensors_doubleecpu-0.0.1-py3-none-any.whl 100%|█████████████████████| 4.65k/4.65k [00:01<00:00, 2.88kB/s] Uploading RaspberryPi3B_Sensors_doubleecpu-0.0.1.tar.gz 100%|█████████████████████| 4.25k/4.25k [00:01<00:00, 3.05kB/s]

Once uploaded the package should be viewable on TestPyPI, Example, https://test.pypi.org/project/RaspberryPi3B_Sensors_doubleecpu

Installing package

 Packages can be installed using pip. Create a new virtualenv (see Installing Packages for detailed instructions) and install package from TestPyPI:

python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps RaspberryPi3B_Sensors_doubleecpu

*Note This example uses –index-url flag to specify TestPyPI instead of live PyPI. Additionally, it specifies –no-deps; pip should install the package from Test PyPI and the output should look something like this:

Collecting RaspberryPi3B_Sensors_doubleecpu
Downloading https://test-files.pythonhosted.org/packages/…/RaspberryPi3B_Sensors_doubleecpu-0.0.1-py3-none-any.whl
Installing collected packages: RaspberryPi3B_Sensors_doubleecpu
Successfully installed RaspberryPi3B_Sensors_doubleecpu-0.0.1

You can test that it was installed correctly by importing the package; either run python venv and >>> import SetupFiles or add to script.