Publishing to PyPI
Using PyPI to distribute my link checker
“pip install ____”, one of my most typed Python related commands- and for good reason. Pip works with PyPI (Python Package Index) to install packages directly to your project with ease. That is why for Haystack (my command-line interface link checker), I went with PyPI as my package distributor.
Creating a Release
Following Python’s official guide here, to create a package to be released you will first need to rearrange your file structure so that it contains a setup file and a Python directory with an initialization file inside. Mine looks something like this:
haystack-link-checker
|- haystack
|- __init__.py
|- tests
|- ...
|- resources
|- ...
|- haystack.py
|- setup.py
|- CONTRIBUTING.md
|- README.md
|- LICENSE
From here, you copy and paste the code below into your newly created setup.py file, and then modify the contents to your liking.
# setup.py
import setuptools
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setuptools.setup(
name="example-pkg-YOUR-USERNAME-HERE", # Replace with your own username
version="0.0.1",
author="Example Author",
author_email="author@example.com",
description="A small example package",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
)
For example, mine looked like this:
import setuptools
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setuptools.setup(
name="haystack-rjayroso",
version="1.0.0",
author="Royce Ayroso-Ong",
author_email="**********************",# change to actual email
description="A command line interface link checker",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/rjayroso/haystack-link-checker",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
)
I already had a README.md setup, so I didn’t need to write one for Haystack- but if this is a fresh project of yours, make sure to fill out your README.md and obtain an open source license before the next few steps.
Now you’ll need to run the following commands to generate a distribution package.
# run this:
python3 -m pip install --user --upgrade setuptools wheel
# and then this:
# NOTE: make sure you run this in the same dir as setup.py
python3 setup.py sdist bdist_wheel
This generated two files in a dist folder. The next step is to create a PyPI account (make sure to generate an API token), and then upload to Test PyPi via twine using the following commands:
# to install twine
python3 -m pip install --user --upgrade twine
# to upload
python3 -m twine upload --repository testpypi dist/*
You will see a username and password prompt, use __token__ as your username and your token as the password (including the pypi- prefix):
Uploading distributions to https://test.pypi.org/legacy/
Enter your username: __token__
Enter your password: pypi-xxxxxx...
Uploading example_pkg_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
100%|█████████████████████| 4.65k/4.65k [00:01<00:00, 2.88kB/s]
Uploading example_pkg_YOUR_USERNAME_HERE-0.0.1.tar.gz
100%|█████████████████████| 4.25k/4.25k [00:01<00:00, 3.05kB/s]
To test if this works, try installing your own package!
python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-pkg-YOUR-USERNAME-HERE
The above steps are what I essentially did to my own project, Haystack (the test PyPI link can be found here). All I need to do now is create a release on GitHub. To do this, I added a v1.0 tag to my final commit and pushed it onto the master branch. Next up I simply used GitHub’s UI to create a release with the v1.0 tag attached. I updated the docs on how to install Haystack using pip and that was it!
Final Notes
I would say that this packaging process was not too too difficult, especially if one follows the documentation to a tee. The only major changes were to the directory structure and adding the necessary packaging files.