How to Publish Your Own Python Package on PyPi: The Ultimate Guide

Python is well known for coming with "batteries included" – a rich standard library that provides a wide range of functionality. But one of Python‘s biggest strengths is the enormous ecosystem of third-party packages available. These packages, most of which are hosted on the Python Package Index (PyPi), extend Python‘s capabilities and allow developers to build all kinds of applications more efficiently.

As a Python developer, you can leverage packages written by others to build your own software. But you can also contribute back to the community by publishing your own Python packages on PyPi for others to use. Sharing a package you‘ve written is a great way to save other developers time and effort.

In this guide, we‘ll walk through the process of publishing a Python package to PyPi step-by-step. By the end, you‘ll be able to transform your code into an installable package available to the worldwide Python community. Let‘s get started!

Prerequisites

Before diving into the publishing process, you‘ll need a few things:

  • Python installed on your machine (version 3.6 or higher recommended)
  • A PyPi account (creating one is free and easy)
  • The code you want to publish, organized into a Python package structure

We‘ll assume you already have Python and an IDE or text editor set up. If you don‘t have a PyPi account yet, head over to pypi.org/account/register/ and create one now.

As for your code, you‘ll want to make sure it is structured as a valid Python package. At a minimum, that means:

  • Placing your Python modules inside a directory (the package name)
  • Including an __init__.py file in that directory (to make it a package)

For example, let‘s say you‘ve written a statistics utility with functions for calculating mean, median, and mode. You could organize it like:

stats/
  __init__.py
  mean.py
  median.py 
  mode.py

The stats directory will become your package name. The __init__.py file can be empty, or you can use it to import objects from the submodules so they are conveniently accessible.

Choosing a Package Name

Before going further, spend some time thinking about what to name your package. The name you choose will be how users import and refer to your code, so pick something concise and descriptive.

Some guidelines:

  • Use all lowercase letters
  • Separate words with underscores if needed for readability
  • Avoid using hyphens, they are not allowed in Python module names
  • Don‘t use names that conflict with standard library modules or very popular packages

To check if a name is already taken, search for it on pypi.org. As of early 2023, PyPi hosts over 400,000 packages, so finding an available name can be tricky!

Creating setup.py

The key to packaging your Python code is writing a setup.py file. This file tells PyPi and tools like pip how to build and install your package.

Here‘s a basic setup.py using the setuptools library:

from setuptools import setup

setup(
    name=‘stats‘,
    version=‘1.0.0‘,
    description=‘A statistics utility package‘,
    author=‘Your Name‘,
    author_email=‘[email protected]‘,
    packages=[‘stats‘],
    install_requires=[],
)

Let‘s break this down:

  • name specifies the package name that will be listed on PyPi and used for installation
  • version is the package version (more on versioning later)
  • description is a one-liner explaining what the package does
  • author and author_email are your information as the package creator
  • packages is a list of package directories to include (just the stats directory in our example)
  • install_requires lists any dependencies your package has (blank in our example)

There are many more optional arguments you can include, like url to point to your project homepage and classifiers to categorize your package. See the setuptools documentation for the full list.

Place your setup.py in the root directory of your project, next to the package directory.

Adding a README and Other Files

It‘s a good practice to include some additional files with your package:

  • A README file introducing your package and explaining how to use it
  • A LICENSE file specifying the terms under which others can use your code
  • Documentation in the form of reStructuredText (.rst) or Markdown (.md) files

At a minimum, you‘ll want a README to let people quickly learn what your package is for. PyPi will display the contents of a README.md or README.rst on your package‘s listing page.

Specifying Dependencies

If your package depends on any other packages to function properly, you need to list them in the install_requires argument to setup(). This allows tools like pip to automatically install the dependencies when installing your package.

For example, if your stats package uses the numpy library, you would change the install_requires line to:

    install_requires=[‘numpy‘],

It‘s considered best practice to specify a minimum version for each dependency, especially if your package requires specific features. You can do this with:

    install_requires=[‘numpy>=1.20.0‘],

This ensures your package has access to the functionality it needs.

Building Your Package

With your code organized and your setup.py written, you are ready to build a distributable package. The standard format for Python packages is the wheel (.whl) format.

To build a wheel, first make sure you have the latest versions of setuptools and wheel installed:

python -m pip install --upgrade setuptools wheel

Then run this command from the same directory as setup.py:

python setup.py sdist bdist_wheel

This will create two directories: dist containing your built .whl file, and stats.egg-info containing metadata about the package.

Uploading to PyPi

Now your package is ready to upload to PyPi! We‘ll use the twine tool for this, which you can install with:

python -m pip install --upgrade twine

To upload your package, run:

python -m twine upload dist/*

You‘ll be prompted for your PyPi username and password. Once entered, twine will upload all the files in the dist directory to PyPi.

Congratulations, your package is now published! It may take a minute or two to be viewable on pypi.org, but once it is, other users can install it with:

pip install stats

Installing and Testing

To make sure your package was uploaded correctly, create a new virtual environment and install your package into it:

python -m venv testenv
testenv\Scripts\activate
pip install stats

Then launch a Python interpreter and try importing your package and using its functionality:

>>>import stats
>>>stats.mean([1, 2, 3]) 
2

If it works, your package was successfully published. Pat yourself on the back!

Updating Your Package

To publish updates to your package, you‘ll need to bump the version number and rebuild. Version numbering follows the standard major.minor.patch format. If you make a backwards-incompatible change, increment the major version. For new features, increment the minor version. For bug fixes, increment the patch version.

Change the version argument in setup.py, then rebuild the wheel file:

python setup.py sdist bdist_wheel

And re-upload with twine:

twine upload dist/*

Users can upgrade to the new version by specifying your new version number:

pip install --upgrade stats==1.1.0

Best Practices for Maintaining a Package

Publishing a package is a major milestone, but the work doesn‘t end there. To be a responsible package maintainer and provide your users with the best experience, follow these practices:

  • Keep your dependencies up to date and remove any that become unnecessary
  • Respond to bug reports and feature requests in a timely fashion
  • Maintain changelogs and release notes detailing what changed in each version
  • Expand your documentation as you add new features
  • Consider using a Continuous Integration service to run tests on new releases

By putting in this effort, you‘ll build trust with your users and create a package that contributes real value to the Python ecosystem.

Conclusion

We covered a lot in this guide: how to structure a Python package, write a setup.py, build a wheel file, upload to PyPi, and maintain your published package. The process may seem involved at first, but it gets easier with practice.

Remember, by publishing packages you are doing a real service to the Python community. Your code could save someone hours of development time or enable them to build something they otherwise couldn‘t.

So go forth and publish! And who knows, maybe your little package will become the next big thing in Python. It all starts with sharing your code.

Similar Posts