Creating a Python Package and publish it to PyPI

You may have install Python packages in the past using PIP, like this:

$ pip install django

Here's my first attempt at created my own public package.

It is a Django app, which add features to the admin. Originally published as django-admin-tools, I have decided to make a version of my own after intensively updating the original source code.

First, I had to make sure that my package could be used independently as a package, so any website project could use it and get the admin extended automatically. I did this by making sure they were no custom settings or custom templates in it, but rather only generic templates that would apply to any project. Custom templates being reserved for the project level.

Then, the code must be hosted publicly, so I have created a public repository on bitbucket here: https://bitbucket.org/guillaumepiot/cotidia-admin-tools, where I keep the latest version of the source code.

I have tagged a version of code in the repository, and get the download link for that version. For that you will need to download a tagged version, and upload it back to the download section of your repository.

$ git tag -a v0.4.1 -m "Version 0.4.1" 
$ git push origin v0.4.1

(How to tag on GIT)

I created the following download link for the current version: https://bitbucket.org/guillaumepiot/cotidia-admin-tools/downloads/cotidia-admin-tools-0.4.1.tar.gz

Please note that although the download url works from Bitbucket, for some reason using a download url from Github will fail. For the code I have hosted on github, I had to upload manually a source code .tar.gz file to the upload section on pypi.python.org

The package source code must be organised in the following manner:

setup.py

You will require at least a setup.py file, which includes instructions about your package:

import os
from distutils.core import setup
from setuptools import find_packages
VERSION = __import__("admin_tools").__version__
CLASSIFIERS = [
    'Framework :: Django',
    'Intended Audience :: Developers',
    'License :: OSI Approved :: BSD License',
    'Operating System :: OS Independent',
    'Topic :: Software Development',
]
install_requires = [
    'django>=1.4.1',
]
# taken from django-registration
# Compile the list of packages available, because distutils doesn't have
# an easy way to do this.
packages, data_files = [], []
root_dir = os.path.dirname(__file__)
if root_dir:
    os.chdir(root_dir)
for dirpath, dirnames, filenames in os.walk('admin_tools'):
    # Ignore dirnames that start with '.'
    for i, dirname in enumerate(dirnames):
        if dirname.startswith('.'): del dirnames[i]
    if '__init__.py' in filenames:
        pkg = dirpath.replace(os.path.sep, '.')
        if os.path.altsep:
            pkg = pkg.replace(os.path.altsep, '.')
        packages.append(pkg)
    elif filenames:
        prefix = dirpath[12:] # Strip "admin_tools/" or "admin_tools\"
        for f in filenames:
            data_files.append(os.path.join(prefix, f))
setup(
    name="cotidia-admin-tools",
    description="Django application to add features to the original admin",
    version=VERSION,
    author="Guillaume Piot",
    author_email="guillaume@cotidia.com",
    url="https://bitbucket.org/guillaumepiot/cotidia-admin-tools",
    download_url="https://bitbucket.org/guillaumepiot/cotidia-admin-tools/downloads/cotidia-admin-tools-0.4.1.tar.gz",
    package_dir={'admin_tools': 'admin_tools'},
    packages=packages,
    package_data={'admin_tools': data_files},
    include_package_data=True,
    install_requires=install_requires,
    classifiers=CLASSIFIERS,
)

AUTHORS

It is important to include who has worked on the code and more importantly any past contributors which may have originated the code.

In my example, I have taken over someone else's work so I have kept their name referenced in that file.

README.md

The holy mardown file. Explaining how to install, configure and manage your package is very important. A non-documented code is just not good enough!

Test

Before register our package with PyPI, it is important to test if the package actually works.

I first install it using the repository as a reference:

$ pip install -e git+https://guillaumepiot@bitbucket.org/guillaumepiot/cotidia-admin-tools.git#egg=admin_tools

Note the '-e' argument. This will keep the source code in a '../src' folder, so it is easily accessible to make further changes if necessary during the development phase, or even for future improvements.

If it all works fine, then you are ready to register it publicly.

Register

You will need an account on pypi.python.org to author a package, so you will need to register first.

Once your account has been confirmed, you will be able to publish your package using the following command:

$ python setup.py register

You will be prompted will an authentication method to complete the registration, where I used my username and password as credentials.

Then a quick look up on PIP revealed my newly published package

$ pip search cotidia
cotidia-admin-tools       - Django application to add features to the original admin

I would definitely recommend to publish a useful package for the community first, but also to improve your workflow building new projects, and keeping your code easy to improve and update across multiple projects.

< / >