I’ve been familiar with the PHP ecosystem for 17 years. I started with PHP 4 and used all subsequent versions in various circumstances. For the last two years, though, I’ve been developing with Python. I came to learn that there is a package installer for Python, which is called pip. Since then, I have been curious to know how I can publish my own packages so that I can download them whenever I want using a package manager. I thought it would take me long, but as it turns out, it was pretty easy.

There is a comprehensive tutorial on packaging Python projects published in the official Python Packaging User Guide. This article is a distilled version of that tutorial for a quick start. If somehow you feel like you are lost or out of options, make sure to check that comprehensive guide.

Prerequisites

First, it’s best to upgrade pip if your version is outdated for uploading packages. You can go without upgrading and come back if you face any problems. On top of pip, you need to install two distributions:

  1. Install build so that you can package your distribution.
  2. Install twine so that you can upload your distribution to pip servers.
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade build
python3 -m pip install --upgrade twine

Secondly, you need to create an account on PyPI. With your PyPI account, you’ll be able to authenticate yourself when uploading your distribution to pip servers. Your published packages will also reside under your registered name on pip.

Directory structure

I created a boilerplate for the easy creation of pip distributions. You can fork it from https://github.com/gzg/sample-pip-distro or clone it using:

git clone https://github.com/gzg/sample-pip-distro.git

You can update the license (MIT by default) and README file to your taste. The file pyproject.toml contains the requirements to prepare your package, and you can keep it as is. The file setup.cfg and the directory src will interest you the most.

Within the file setup.cfg, you can set up the name and the version of the package. You’ll want to set up the author and the package description as well. You can also list the package requirements here. Check setuptools’ user guide for the complete list of options you can use within this configuration file.

The directory src, on the other hand, is where your source code resides. You can structure your subdirectories under src however you want. The number one rule you need to follow is to create an at least empty __init__.py file inside any directory you’d like to reach by an import statement. Creating __init__.py files is for telling Python that the directory is a module. As a Python noob, I had spent more time than I care to admit until I found out I was missing __init__.py files in my modules.

Packaging your directory

Go back to your root directory where your pyproject.toml file resides. Now you can build the distribution files:

python3 -m build

When the build command is finished running, you’ll have two files under the newly created dist directory:

pkg-name-version.tar.gz
pkg_name-version-py3-none-any.whl

Now you can upload these distribution files to pip servers:

python3 -m twine upload dist/*

That’s it! You’ll be prompted with a link to your package listed on PyPI. Here is an example page for the boilerplate repository as a package: https://pypi.org/project/example-pkg-pip/0.0.1/

Downloading your package

You can now download your package using pip:

python3 -m pip install [your-package]