Uploading Code to PyPi
These are the steps I usually take when I want to upload a python package to PyPi. I assume that you already have an account on PyPi and your code is already on GitHub. As always, there are probably a million ways to do this, but this is how I do it.
1. Make the package installable
The first step to make you package easily installable is to create a standard structure for your package. I usually
my_package
├── my_package
│ ├── __init__.py
│ └── my_module.py
├── LICENSE
├── README.md
├── setup.py
├── pyproject.toml
├── requirements.txt
└── .gitignore
The my_package
folder contains the actual code of your package. The LICENSE
file contains the license of your
package. The README.md
file contains the description of your package. The .gitignore
is optional and
contains information about which files should and which should not be tracked by git, but I would
recommend to use it. The tests
folder contains the tests for your package.
The files we will go over in more detail are the setup.py
and the pyproject.toml
file.
The setup.py file
There are two possibilities to use the setup.py file. One is to put all the information, needed for installation, in
here. The other is to use the pyproject.toml file to store the information and use the setup.py file only to call the
setup
function. I prefer the second option, because it is easier to read and understand. In this case the complete
content of the setup.py
file is:
from setuptools import setup
setup()
The pyproject.toml file
Since we kept the setup.py
file very simple, we have to put all the information needed for installation in the
pyproject.toml
file. The content of the file is:
[build-system]
requires = ["setuptools>=61.0", "setuptools_scm[toml]>=6.2"]
build-backend = "setuptools.build_meta"
[project]
name = "my-package"
dynamic = ["version", "readme", "dependencies"]
authors = [
{ name="Your Name", email="my@email.com" },
]
description = "My awesome tool."
requires-python = ">=3.9"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Operating System :: POSIX :: Linux",
]
[project.urls]
"Homepage" = "https://github.com/my_account/my_package"
"Bug Tracker" = "https://github.com/my_account/my_package/issues"
[tool.setuptools]
packages = ["my_package"]
[tool.setuptools_scm]
write_to = "my_package/_version.py"
[tool.setuptools.dynamic]
readme = {file = ["README.md"]}
dependencies = {file = ["requirements.txt"]}
There are a few things to note here.
-
See how the project name is using the dash instead of the underscore. This is a convention that is used by most python packages. So to install you would use
pip install my-package
, but to import its content you would doimport my_package
. -
We use a dynamic version number. How this works is explained in the next section.
With these 2 files in place, you can already install your package locally by running pip install .
in the root
directory of your package. You should try this to make sure that everything is working as expected.
2. Create a git tag
The next step is to create a git tag. This is necessary to make sure that the version number of your package is correctly set. To create a git tag, first commit any changes you made to your code and then run the following command:
git tag -a v0.1.0 -m "First release"
This will create a git tag with the name v0.1.0
. The name of the tag is important, because it is used as the version
number of your package. The -m
flag is optional and is used to add a message to the tag.
You would now probably want to push the tag to your remote repository. To do this, run the following command:
git push origin v0.1.0
3. Create distribution files
The next step is to create the distribution files. These are the files that are uploaded to PyPi. If you have followed the previous steps correctly, this should be very easy. Just run the following command:
python -m build
This will create a dist
folder in your root directory. This folder contains the distribution files.
4. Upload to PyPi
The last step is to upload the distribution files to PyPi. To do this, run the following command:
twine upload dist/*
This will upload all the files in the dist
folder to PyPi. You will be asked for your username and password. After
entering them, the upload should start.
If you want to upload a new version of your package, you have to repeat steps 2 to 4.
To check if everything worked as expected, you can install your package from PyPi by running:
pip install my-package
5. Add executable scripts (optional)
If you have executable scripts in your package, you can add them to the project.scripts
section of the pyproject.toml
file. After installation, you should be able to call the scripts from anywhere on your system. If you want to see an
example for this, have a look at my
slurm resource monitor.