Distributing Python Packages Part II: Submitting to PyPI
In
Part
I, I discussed writing a setup.py
to make a package you can submit to PyPI.
Today I'll talk about better ways of testing the package,
and how to submit it so other people can install it.
Testing in a VirtualEnv
You've verified that your package installs. But you still need to test it and make sure it works in a clean environment, without all your developer settings.
The best way to test is to set up a "virtual environment", where you can install your test packages without messing up your regular runtime environment. I shied away from virtualenvs for a long time, but they're actually very easy to set up:
virtualenv venv source venv/bin/activate
That creates a directory named venv under the current directory,
which it will use to install packages.
Then you can pip install packagename
or
pip install /path/to/packagename-version.tar.gz
Except -- hold on! Nothing in Python packaging is that easy. It turns out there are a lot of packages that won't install inside a virtualenv, and one of them is PyGTK, the library I use for my user interfaces. Attempting to install pygtk inside a venv gets:
******************************************************************** * Building PyGTK using distutils is only supported on windows. * * To build PyGTK in a supported way, read the INSTALL file. * ********************************************************************
Windows only? Seriously? PyGTK works fine on both Linux and Mac; it's packaged on every Linux distribution, and on Mac it's packaged with GIMP. But for some reason, whoever maintains the PyPI PyGTK packages hasn't bothered to make it work on anything but Windows, and PyGTK seems to be mostly an orphaned project so that's not likely to change.
(There's a package called ruamel.venvgtk that's supposed to work around this, but it didn't make any difference for me.)
The solution is to let the virtualenv use your system-installed packages, so it can find GTK and other non-PyPI packages there:
virtualenv --system-site-packages venv source venv/bin/activate
I also found that if I had a ~/.local directory (where packages
normally go if I use pip install --user packagename
),
sometimes pip would install to .local instead of the venv. I never
did track down why this happened some times and not others, but when
it happened, a temporary
mv ~/.local ~/old.local
fixed it.
Test your Python package in the venv until everything works.
When you're finished with your venv, you can run deactivate
and then remove it with rm -rf venv
.
Tag it on GitHub
Is your project ready to publish?
If your project is hosted on GitHub, you can have pypi download it automatically. In your setup.py, set
download_url='https://github.com/user/package/tarball/tagname',
Check that in. Then make a tag and push it:
git tag 0.1 -m "Name for this tag" git push --tags origin master
Try to make your tag match the version you've set in setup.py and in your module.
Push it to pypitest
Register a new account and password on both pypitest and on pypi.
Then create a ~/.pypirc that looks like this:
[distutils] index-servers = pypi pypitest [pypi] repository=https://pypi.python.org/pypi username=YOUR_USERNAME password=YOUR_PASSWORD [pypitest] repository=https://testpypi.python.org/pypi username=YOUR_USERNAME password=YOUR_PASSWORD
Yes, those passwords are in cleartext. Incredibly, there doesn't seem to be a way to store an encrypted password or even have it prompt you. There are tons of complaints about that all over the web but nobody seems to have a solution. You can specify a password on the command line, but that's not much better. So use a password you don't use anywhere else and don't mind too much if someone guesses.
Update: Apparently there's a newer method called twine that solves the password encryption problem. Read about it here: Uploading your project to PyPI. You should probably use twine instead of the setup.py commands discussed in the next paragraph.
Now register your project and upload it:
python setup.py register -r pypitest python setup.py sdist upload -r pypitest
Wait a few minutes: it takes pypitest a little while before new packages become available. Then go to your venv (to be safe, maybe delete the old venv and create a new one, or at least pip uninstall) and try installing:
pip install -i https://testpypi.python.org/pypi YourPackageName
If you get "No matching distribution found for packagename", wait a few minutes then try again.
If it all works, then you're ready to submit to the real pypi:
python setup.py register -r pypi python setup.py sdist upload -r pypi
Congratulations! If you've gone through all these steps, you've uploaded
a package to pypi. Pat yourself on the back and go tell everybody they
can pip install
your package.
Some useful reading
Some pages I found useful:
A great tutorial except that it forgets to mention signing up for an account: Python Packaging with GitHub
Another good tutorial: First time with PyPI
Allowed PyPI classifiers -- the categories your project fits into Unfortunately there aren't very many of those, so you'll probably be stuck with 'Topic :: Utilities' and not much else.
Python Packages and You: not a tutorial, but a lot of good advice on style and designing good packages.
[ 16:19 Dec 17, 2016 More programming | permalink to this entry | ]