Blogs

Ronie Martinez

May 19, 2017

Submitting a Package to PyPI

Python programmers are very familiar with easy_install and pip when installing open-source python packages. But how do these packages really end up in our code?

PyPI - the Python Package Index

As quoted from the official PyPI page.

The Python Package Index is a repository of software for the Python programming language.

Registering to PyPI

Before your package end up in the PyPI repository, you will need to register first.

Registration to PyPI Test is optional but you can use it to test your package.

The ~/.pypirc

In order to prevent manually entering usernames and passwords when registering and uploading a package to PyPI, the ~/.pypirc comes in handy. Quoted from the official PyPI documentation.

The register and upload commands both check for the existence of a .pypirc file at the location $HOME/.pypirc. If this file exists, the command uses the username, password, and repository URL configured in the file.

[distutils]
index-servers =
  pypi
  pypitest

[pypi]
repository=https://pypi.python.org/pypi
username=<pypi_username>
password=<pypi_password>

[pypitest]
repository=https://testpypi.python.org/pypi
username=<testpypi_username>
password=<testpypi_password>

Project Structure

As an example project, I will be writing a very useful application DogYears - Convert human years to dog years and vice versa. The files README.md, CHANGELOG.md and LICENSE are optional, but they will serve as example to explain the MANIFEST file.

|- DogYears
| |- dogyear
| | |- __init__.py
| |- MANIFEST
| |- README
| |- setup.cfg
| |- setup.py
| |- README.md
| |- CHANGELOG.md
| |- LICENSE

The dogyear Package

For a more accurate calculation, I used the chart from How To Calculate Dog Years article and used numpy for linear interpolation. You can check my code in Github.

The setup.py

Details including name, version, url, download_url, license, author, author_email and description should be self-explanatory and does not need a special section.

#!/usr/bin/env python
from distutils.core import setup

setup(
    name='DogYears',
    version='1.0.0',
    packages=['dogyear'],
    url='https://github.com/Code-ReaQtor/DogYears',
    download_url='https://github.com/Code-ReaQtor/DogYears/archive/1.0.1.tar.gz',
    license='MIT',
    author='Ronie Martinez',
    author_email='ronmarti18@gmail.com',
    description='Convert human years to dog years and vice versa.',
    install_requires=['numpy==1.12.1'],
    classifiers=[
        'Development Status :: 3 - Alpha',
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3'
    ]
)

The packages List

This is a list of Python packages that will be included to your PyPI package.

The install_requires List

If your packages requires external packages to work, you will need to indicate these packages on this list. The version is optional, which means that without it, the latest version will be installed. Thus, install_requires=['numpy==1.12.1'] can be rewritten as install_requires=['numpy'].

The classifiers List

This entry is optional, but if you want better structure to your project and be easily indexed and identified in PyPI, you can find the complete list here.

The MANIFEST

By default, only Python extensions will be included to your package. If you need to include extensions like *.db, *.csv, etc., you can use this example.

setup.cfg
README
LICENSE
setup.py
dogyear/__init__.py
CHANGELOG.md

The README

The README file is very important as it includes details of your project, installation instructions, usage, references, etc. PyPI requires reStructure Text format for your project description. Most people [like me] are more comfortable in writing Markdown files as this format is also use in repositories like Github. To convert from Markdown to reStructured Text, tools like Pandoc can be used.

pandoc -t RST -o README README.md

The setup.cfg

In order to tell PyPI where to find you README file, you can use the following.

[metadata]
description-file = README

Registering and Uploading to PyPI

PyPI Test

python setup.py register -r pypitest
python setup.py sdist upload -r pypitest

PyPI Live

python setup.py register -r pypi
python setup.py sdist upload -r pypi

Result

References