Build Your Custom Python Package  and  Publish It on PyPI

Build Your Custom Python Package  and  Publish It on PyPI

Author: Fortune Uwha

Python allows you to reuse code and share your code to save time and energy. So, you’ve created some convenient script that you would like your coworkers or others to use – what’s next? This article tackles the problem of packaging and distribution. We’ll focus on transforming your code into a python package so that people can easily install it.

At the end of this article you will be able to :

  • Understand the requirements of a Python package
  • Build a Python package or transform an existing project into a package
  • Pip install the self-built package

First of all, why use a Python package?

Meme about unmanageable code
Image Source: Head First Python, 2nd Edition by Paul Barry

Why build a Python package?

Imagine you have to write your code from scratch every time you want to parse a file in a particular format. You’d never get anything done! Packages are an essential building block in programming. Without packages, we’d spend lots of time writing code that’s already been written. That’s why we always want to use packages. Packages are the manifestation of Python’s concept of hierarchical namespaces. To quote from the Zen of Python:

“Namespaces are one honking great idea — let’s do more of those!”

To view the entire Zen of Python, type import this in a Python code cell. Even if you never want to give anyone else your code, a well structured package simplifies development.

Building Your Own Python Package

Now it's time to package your code. Here’s the basics of what you need to know to make your own package.

Basic structure:

Basic structure of a Python package

Let’s go through this files one-by-one:

  • Package name(calculator): Create a folder with the name of your package. In my case, this is a “calculator”. This will be the package we’re installing. Place all the files and classes that you want to ship into this folder. Packages should have short, all lowercase names. Except for cases where it helps improve readability, the use of underscores in a package's name is discouraged.
  • __init__.py: This file lets python know that the directory we created is a package and there is no flexibility in the naming. If you remove the __init__.py file, Python will no longer look for submodules inside that directory, so attempts to import the module will fail. The __init__.py file is usually empty, but can be used to export selected portions of the package under more convenient names, hold convenience functions, etc.
  • tests: One thing everyone learns is that people make mistakes. That’s why pencils have erasers, why computers have spell check, and why our code needs tests. We trust that our code will run, but we must verify:). There are a few tests in a separate directory. The tests will not be covered here, but you can learn more about testing, see Anthony Shaw’s great tutorial on getting started with testing in Python.
  • license: Licensing is pretty common in our technological world. There are many different types of legal documents that you can use to protect your code. Sometimes a license is required for your project when you're creating a Python package, but generally, it is always a good practice to have one anyway. To learn more about the different types of software license, check here. For this sample project, I have used an MIT license. If you’re unsure which license to choose, you can use resources such as GitHub’s choose a license
  • README.md: Your python package should always have a well written README file as it not only shows the quality of your project but also provides information that is easy to read and access. Here is a cool blog post that explains the README structure in more details and contains a free template you can use.
  • setup.py: This is what tells pip how to install our actual package. This contains a single call to the setup function from the “setup tools'' package. Setuptool is one of the most common and powerful. The documentation does a good job of going into all the details. The parameters that are100% necessary in the call to setup() are the following:
  • name: the name of your package as it will appear on PyPI
  • version: the current version of your package. There are many different schemes that can be used for your version number. For Python projects, PEP 440 gives some recommendations. However, in order to be flexible, PEP is complicated. For a simple project, Semantic Versioning is a good default scheme to use. An example for our sample project is version: 0.0.1.
  • packages: the packages parameter takes a list of packages. In our example, there is only one package: calculator. In larger projects, there might be many packages to list. To simplify this job, setuptools has a feature find_packages(), which does a good job of discovering all your subpackages.

You can find an example of these files listed in configuring your project in the Pypa sample github project repo here.

Upload Python Package on PyPI

Hands wrapping a gift with beige paper and a black ribbon
Image Source: Pexels

Now your code is properly packaged and ready for the world to see! Give yourself a pat on the back if you have made it this far, you have made good progress and you are almost there:). In this section, you’ll see how to actually upload your package to PyPI.

First things first, you will need an account on PyPI. If you don’t already have an account, now is a good time to create one. You can register yourself for a PyPi account here. Remember your username (note: not the name, not the email address) and your password, you will need it later for the upload process.

Final Steps

Open folder in command prompt where all package information is stored. For instance:

cd "C://PATH//TO//YOUR//FOLDER"

Next, we will use a tool called Twine. You can install Twine using pip:

pip install twine

Packages on PyPI are not distributed as plain source code. Instead, they are wrapped into distribution packages. The most common formats for distribution packages are source archives and Python wheels. To create a source archive and a wheel for your package, we can run this command:

python setup.py bdist_wheel

Now the moment you have been waiting for, one last command!

twine upload dist/*

Remember to provide your username and password when requested and that’s it! Congratulations on uploading your first python package, visit https://pypi.org/project/your-package-name/ to view your package on PyPI.

Install Your Custom Package Using pip on PyPI

Seeing your own code installed by pip is a wonderful feeling! Want to try? You can install your newly uploaded package on PyPI by:

pip install your-python-package

Install Your Custom Package Using pip on GitHub

Alternatively, You can pip install your code directly from Github.

  • Create a Repository and push all your code files to that repo (like we have done above).
  • Copy the URL of your repository. You can now pip install by:

pip install git+https://github.com/username/your-awesome-package.git

Conclusion

This article gives you the basics of the why, what and how a python package is built and uploaded to PyPI. It’s safe to assume that you probably encountered a lot of errors as you tried to do this.I know I did :) But thanks to stackoverflow it was all fixed in the end. So my final advice to you would be this, google errors as you try to work your way through everything and bit by bit you will be on your way to making the world a better place by writing reusable and shareable code!