Tips on publishing your Python package to PyPI

 


If you want to publish your first Python package to PyPI, here are some tips that might help you in avoiding some pitfalls when releasing your code to the world.

Table of contents


1. Unsupported reST directives and other limitations

The README.rst[1] that you painstakingly wrote for readthedocs.org[2] might not render correctly on PyPI, nor on GitHub[3]. Here are some of the limitations that you need to look carefully for each website on which you might be publishing your documentation.

IMPORTANT: I am only referring to the reST markup language. 

1.1 PyPI limitations

Many reST directives and roles are not supported on PyPI since they support reST without Sphinx extensions. Thus, raw, admonitions, labels, code-block's options (e.g. :emphasize-lines:) and roles for cross-referencing modules, methods, and classes (e.g. :mod: and :meth:) are not recognized and you need to find replacement solutions. 

For instance instead of using the standard warning directive, you can create your own warning message by indenting the text and preceding it by a non-indented bolded title:
**Warning**

   Warning text is written here.

On GitHub, you can use their emoji emoticons to title your block text like this:
`:warning:`

   Warning text is written here.

The preceding code will render like this:
I recommend using the twine tool to validate your documentation for PyPI. If you don't have twine, you might have to install it eventually anyway since it is recommended for uploading your distribution archives to PyPI, as explained under Uploading the distribution archives (from PyPA's tutorial Packaging Python Projects).

This is how you use twine to check your documentation:
$ twine check dist/*

where dist contains your generated distribution archives as described under Generating distribution archives (from PyPA's tutorial Packaging Python Projects)

1.2 GitHub limitations

The same limitations as for PyPI, except that GitHub accepts the raw directive.

1.3 Limitations for all

Don't rely too much on the ids that are automatically generated for each section of your document. These ids are used for building your internal links and are usually based on the corresponding section titles but unfortunately they will sometimes be based on numbers (e.g. id4) instead of the section titles. 

Some images might not render correctly by having text wrapping around them and therefore you will have to add newlines after the images to avoid this situation. Unfortunately not the same number of newlines might be required for all sites. Thus you have to experiment.

As you can see from the different quirks that you must take into account when writing your README for the different sites, you will have to streamline the process of generating the README for the different sites so you don't have to modify each of them separately which would be time consuming. 

2. Versioning your project

If not already done, you need to provide a version X.Y.Z to your project. To know more about versioning (e.g. what each number represents and how they should be incremented), there are two documents that I recommend:

3. Validate your documentation before uploading

As explained previously, use twine to validate your documentation before uploading your Python package to PyPI:
$ twine check dist/*

where dist contains the distribution archives you previously generated with:
$ python setup sdist bdist_wheel

Check PyPA's tutorial Packaging Python Projects on how to build a package (i.e. distribution archives) and upload it to PyPI.

4. Make a release

Once you are ready to publish your package to PyPI, you can now freeze your code on GitHub (or any other repo site), and make a release using the project's version as tag. A tag will be created and associated with this new release. Now, when you build your documentation on readthedocs.org, people will have the possibility to also look at documentation from specific project versions.

It is strongly recommended to sign your tag locally before pushing it to your GitHub repo. Check the documentation from GitHub to know how to sign tags locally using GPG or S/MIME.

5. Publishing first to TestPyPI

Publish your package first to the test version of PyPI: TestPyPI. Once you have thoroughly tested that your documentation renders correctly and that you are able to download and install the package fine from TestPyPI, you can publish your package to the real PyPI, with high confidence that everything will turn out right so you don't have to re-release.

6. Mistakes found in a published README

If you uploaded your package to PyPI and found out some mistakes in your README, you can't edit the file right away from the PyPI website. You will have to fix the documentation from your code repository, generate and upload again the distribution archives to PyPI but this time modify the project's version by appending the string .postN to your project's version, e.g. 0.0.1.post1 

The suffix post will let your users know that the latest version of your package is a post-release where some minor modifications to the documentation were applied.

NOTE: according to the PEP 440 document, under Post-releases, it is not recommended to create a post-release of a pre-release since the version number will be difficult to parse for human readers. It is better in that case to create a new pre-release by incrementing the numeric component. 

7. Remove a release from PyPI

If you want to definitely remove a release from PyPI [4], be careful that if you do so, you won't be able to re-use the version number from the deleted release ever again, as per PyPI's instructions:
You will not be able to re-upload a new distribution of the same type with the same version number. 
However, instead of deleting a release, you can yank it which means that the release will be ignored when installing in most common scenarios. The users can still install it with pip install by providing the full version number but they will be warned (on the PyPI website or terminal) that they are about to install a release that was yanked for a given reason. Eventually, you can also un-yank the release through PyPI's website.

8. Conclusion

I think that is all I had to share about tips for publishing to PyPI. I wish you good luck with releasing your project to the whole wide world! It is a lot of work since there will be more people using your package and as a result it will only grow in complexity (bug fixes, new features, more documentation) but you will learn a lot in the process and become a better developer in the long run, or just rage quit.

9. Resources


Image source: https://www.zdnet.com

10. Notes

  1. ^ If you use another markup language like Markdown (GitHub Flavored Markdown), you should test your documentation on TestPyPI first (not the real PyPI) and find out what works and what doesn't. Then when you have everything figure out about the changes needed to be applied to the README in order to display it correctly on PyPI, you can now upload your package to the regular PyPI.
  2. ^ Not only are you going to publish your Python package to PyPI and GitHub but your API documentation needs to be shared too. It is a lot of work to maintain a library but very well-documented packages will likely attract lots of attention from developers eager to install it (and probably break it which is good since you will make your code more robust by fixing it) if they find it interesting and easy to understand by looking at the documentation.
  3. ^ I talk about GitHub because that is what I have been using to store my personal projects but if you use another repo site, you should make tests uploading your documentation and checking whether it renders correctly before publishing your code to PyPI.
  4. ^ Maybe you made a mistake numbering your version and uploaded the faulty package to PyPI. Take your time when versioning your code because it will follow you forever in the Changelog  or Release notes, among many other places.

Comments

Popular posts from this blog

Install the MAMP (Mac, Apache, MySQL, PHP) stack

Deactivate conda's base environment on startup

Product review: SMONET wireless security camera system