• How To Publish A Package On PyPI

publishing on PyPI

Python has a long history of development and the significant contributions to this process were made by the open source volunteers and supporters. As the famous Isaac Newton said: “If I have seen further it is by standing on the shoulders of Giants”. The same can be said about the development of language capabilities - some developers are using the developments written before them to create something new and useful. And their own developments are also becoming the foundation for someone’s projects and so on. But in order for this mutual assistance scheme to work, you need a convenient way to exchange projects (both in small scripts and in serious packages and libraries).

Perhaps the most popular repository for this purpose is PyPI. Currently there are more than 150,000 projects (totalling 1.5 million files), and over a quarter of a million Python-developers from all over the world are registered on the site.

In this article we’ll talk about how to place your project on PyPI, so that other programmers can also use your developments.

Making a publication

First of all, you need to have the code you want to share. For example, we’ll use this simple program:

def say_hello(name=None):
    if name is None:
        return 'Hello, World!'
    else:
        return 'Hello, {}!'.format(name)

saved to helloworld.py

This file you need to put in the src folder, and the folder itself - in the project folder. Let's call it helloworld. Thus, you should have the following file and folder tree:

helloworld
└──src
     └──helloworld.py

After that, you need to add the setup.py file to the project (it must be placed in the helloworld folder, next to the src folder) with the following content:

from setuptools import setup

setup(
    name = 'helloworld',
    version = '0.0.1',
    description = 'Say hello!',
    py_modules = ['helloworld'],
    package_dir = {'': 'src'},
)

In this example, we present one of the simplest setup.py you can write. In reality, the amount of various information may be much more.

    The arguments that you pass to the setup function described above indicate the following:
  • name is the name of your library. This name will be stored in the PyPI database and used during the library installation with pip (that is, the installation process will be started with the pip install helloworld command (or pip3 instead of the pip on Linux). Considering the huge number of packages and libraries that are already on PyPI, you have to be careful with the choice of a name so that it doesn’t coincide with any of the 150,000 that already exist there.
  • version is the current version of your project. At the moment, we have set 0.0.1, as there are still many improvements ahead of it before the library becomes really useful (at least it would be worth doing if it were a real project and not an abstract one). The version number is important because it also can (and will) be used later in the installation process, for example, pip install helloworld==1.0.2 or pip install helloworld>=1,<2. The version number for installation and integration into your project is chosen by developers on the basis of what functionality this or that release has.
  • description is a brief description on which you don’t really have to focus too much attention. A couple of phrases will suffice, since all the key information about the library will be located in a different place (which we’ll talk about later).
  • py_modules is the py-file that will be uploaded to PyPI. In most cases, this name is the same as the one specified in name.
  • package_dir - points to the folder where our program is located (helloworld.py)
Once this has been done, it’s worth testing the library locally. First, run the following command:

python3 setup.py bdist_wheel

After that, several new folders and files will be added to the folder with your project.

Now the library is ready for installation and we can install it locally using the command:

pip3 install -e .

-e means that we’re installing the editable version, so the library files aren’t being copied, and only a connection is being made to the original source code and all changes that we’re making to helloworld.py are also going to be taken into account when importing our module into the code of other programs.

. means that we’re using the current directory for installation.

Finally, you can import the installed module and check that everything works correctly. We’ll look at how the module works in the console, but in a regular Python-script file it will work in a similar way.

>>> import helloworld

>>> helloworld.say_hello()
'Hello, World!'
>>> helloworld.say_hello('Mike')
'Hello, Mike!'

We can also import not only the entire module, but also the individual functions from it (although the choice in the current version is quite small).

>>> from helloworld import say_hello

>>> say_hello()
'Hello, World!'
>>> say_hello('everybody!!')
'Hello, everybody!!!'

Theoretically, at the moment our project is ready for publication on PyPI, since its performance has successfully passed the test. However, there are several points that would be worth improving.

First of all, you should add the gitignore file so that the extra files don’t get into the final product. The gitignore.io website, which allows you to create a gitignore file depending on the programming language, operating system, IDE, etc., can help you with that. In our case, you can use the file for the Python language.

The second thing to take care of is the license. Although the libraries hosted on PyPI are open source, various licenses grant different rights to the developers who will use your product. For example, the difference between the MIT and GNU General Public License v3.0 licenses is that the former grants almost unlimited rights to use your code, including the creation of closed source programs on its basis. The second license also provides a lot of rights, but prohibits using your work for the creation of projects with closed source code.

For more information, you can familiarize yourself with the license types on choosealicense.com.

After selecting a license, you just need to save its text in the LICENSE.txt document and put it in the root folder of the project.

Then, you can facilitate the categorization process of your project by adding relevant information to the setup.py file. For example:

setup(
…
    classifiers=[
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "License :: OSI Approved :: GNU General Public Licence v2 or later (GPLv2+)",
         "Operating System :: OS Independent",
       ],
)

You can read more about the classifiers in the appropriate section on PyPI.

The next step is to add the README.md file, which will contain key information about the project, installation, etc., that is, everything that the person started to get acquainted with your library should read in the first place.

In our case, the information in this file might look like this:

# Hello World

This is an example project demonstrating how to publish Python module to PyPI.

## Installation

Run the following to install:

>>>pip3 install helloworld

## Usage

from helloworld import say_hello

#Generate ‘Hello, World!’

say_hello()

#Generate ‘Hello, Everybody!’

say_hello(‘Everybody’)

Now that we have a README file with a more or less detailed description of the project, we can add it to setup.py:

from setuptools import setup

with open(‘README.md’, ‘r’) as fh:
    long_description = fh.read()

setup(
    …
    long_description = long_description,
    long_description_content_type = ’text/markdown’, 
)

In addition, you might want to add to the setup.py the information about the project’s repository on GitHub, something about the author and an e-mail. It might look like this:

setup(
    …
    url = ’https://github.com/username/project_repository’,
    author = ’name surname’,
    author_email = ’e-mail’,
)

Finally, when added all the key information, you can proceed to the publication of our library. First, execute the command:

python3 setup.py bdist_wheel sdist

and check the contents of the dist folder:

ls dist/
helloworld-0.0.1-py3-none-any.whl
Helloworld-0.0.1.tar.gz

After making sure that the necessary files are in place, you can proceed to registering the user on PyPI (if you haven’t done it yet). Now you need to install a special tool for publishing packages on PyPI - twine. This can be done with the command:

pip3 install twine

after which you can start uploading files to the server:

twine upload dist/*

In this case, you’ll need to enter the username and password that you’ve provided during registration. You can also specify them in the ~/.pypirc file, so that you don’t have to enter it manually every time. The contents of the .pypirc file with the specified login and password will look like this:

[distutils]
index-servers = pypi
[pypi]
repository = https://upload.pypi.org/legacy/
username = [your username]
password = [your password]

After performing all the actions described above, your module/package/library will appear on PyPI and developers from all over the world will be able to use it in their projects.

You can also familiarize yourself with the checkio client - a tool, which we’ve already wrote about earlier in the corresponding article and which is also available on PyPI.

Conclusion

As you may have noticed, publishing on PyPI is not a particularly difficult task (perhaps that is why over the past 2 years the number of packages there has almost doubled - from 80 thousand to 150).

Did you have to publish your work on this resource? Or maybe you were involved in improving the projects of other people who were in the early stages of development?

Welcome to CheckiO - games for coders where you can improve your codings skills.

The main idea behind these games is to give you the opportunity to learn by exchanging experience with the rest of the community. Every day we are trying to find interesting solutions for you to help you become a better coder.

Join the Game