Basic setup
At best start from a fresh conda
/ mamba
environment and make sure the setuptools
package (usually is) as well as the twine
package (usually is not) are available. If not then simply type,
pip install setuptools
pip install twine
Make a distribution
Two steps to making a source distribution (the file which you will upload to PyPI later).
First, check if your setup.py
file provides all necessary meta-data to make PyPI happy. Run this check with,
python setup.py check
If no errors are raise, then proceed with creating the source distribution,
python setup.py sdist
This will create (if not available) a dist
folder and a tar.gz
file with a file name roughly like packagename-version.tar.gz
.
Test upload
We can now test-run an upload to PyPI via the TestPyPI server (Test Python Package Index).
To upload our just-created source distribution, we will type the following in the terminal.
twine upload --repository-url hhtps://test.pypi.org/legacy/ dist/packagename-version.tar.gz
Test install
To test-run an install from TestPyPI, we type,
pip install --index-url https://test.pypi.org/simple/ packagename --user
One may run into issues with dependencies, in which case the extra argument --extra-index-url https://pypi.org/simple
can (it did in my case) help.
The full command in this case:
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ packagename --user
The real thing
If the test install suceeded (consider trying it in fresh conda / mamba environments across a few python versions), we can now confidently upload our distribution to to PyPI. Simply type,
twine upload dist/packagename-version.tar.gz
You will be asked for your username and password. Once the upload finished, you can try installing your package via the standard pip install
command like so,
pip install packagename
MANIFEST
The sdist
command, will not necessarily include all the files in your package folder that are important for an actual installation of your package (e.g. if you have a src
subfolder which includes a few .c
or .pyx
files). To explicitly include (and exclude) specific files and subfolders in the source distribution, you need to add a MANIFEST.in
file. The concent of these MANIFEST.in
files follows a specific syntax, which you can find in the documentation.
Below an example:
recursive-include docs
include README.md LICENSE
include mypackage *.py
include src/*.pyx
include notebooks/*
global-exclude .gitignore
global-exclude .git
global-exclude *~
global-exclude *.pyc
global-exclude .#*
Some Credits
This tutorial is a slightly adapted, mostly much reduced version of this excellent blog post.