If you are like me, every once in a while you write a useful python utility and want to share it with your colleagues. The best way to do this is to make a package: it easy to install and saves from copy-pasting.

If you are like me, you might be thinking that creating packages is a real headache. Well, that’s not the case anymore. And I am going to prove it with this step-by-step guide. Just three main steps (and a bunch of optional ones) accompanied by few GitHub links. See for yourself:

1. Stub

We will create podsearch - a utility that searches for podcasts in iTunes. Let’s create a directory and a virtual environment:

$ mkdir podsearch
$ cd podsearch
$ python3 -m venv env
$ . env/bin/activate

Define a minimal package structure:

.
├── .gitignore
└── podsearch
    └── __init__.py

"""Let's find some podcasts!"""

 __version__ = "0.1.0"

 def search(name, count=5):
     """Search podcast by name."""
     raise NotImplementedError()

2. Test package

Creating a package in Python used to be a troublesome task. Fortunately, nowadays there is a great little flit utility which simplifies everything. Let’s install it:

pip install flit

And create package description:

$ flit init
Module name [podsearch]:
Author [Anton Zhiyanov]:
Author email [m@antonz.org]:
Home page [<https://github.com/nalgeon/podsearch-py>]:
Choose a license (see <http://choosealicense.com/> for more info)
1. MIT - simple and permissive
2. Apache - explicitly grants patent rights
3. GPL - ensures that code based on this is shared with the same terms
4. Skip - choose a license later
Enter 1-4 [1]: 1

Written pyproject.toml; edit that file to add optional extra info.

Flit has created pyproject.toml - the project metadata file. It already has everything you need to publish the package to the public repository - PyPI.

Sign up for TestPyPi (test repository) and PyPI (the main one). They are completely independent, so you will need two accounts.

Setup access to repositories in the ~/.pypirc:

[distutils]
index-servers =
  pypi
  pypitest

[pypi]
username: nalgeon  # replace with your PyPI username

[pypitest]
repository: <https://test.pypi.org/legacy/>
username: nalgeon  # replace with your TestPyPI username

And publish the package to the test repository:

$ flit publish --repository pypitest
Found 4 files tracked in git
...
Package is at <https://test.pypi.org/project/podsearch/>

Done! The package is available on TestPyPi.