Friday, June 8, 2018

Creating pip Packages For Distribution And Reusability

Prerequesites


  • Python 2 or 3 installed.  Both versions are bundled if you are using macOS.  
  • pip (Pip Installs Python/Packages) installed.  pip is bundled with Python 2.7 and above.  If pip is not bundled for whatever reason, follow steps below:
    • Download get-pip.py file
    • Run command python get-pip.py install to install pip
  • setuptools and wheel installed.
    • (Using Python 2) python -m pip install --user --upgrade setuptools wheel
    • (Using Python 2) python3 -m pip install --user --upgrade setuptools wheel
  • twine installed.  
    • (Using Python 2) sudo pip install twine
    • (Using Python 3) sudo pip3 install twine
  • Register a new account at PyPI


Creating First pip Package


Basic folder structure for a pip package should look like the following:

inkipackage
    inkipackage
        __init__.py
        module.py
    setup.py

Top level inkipackage is the root directory of our pip package.  inkipackage below is the base level of Python module of the pip package, which will contain multiple modules to be imported.

In the inkipackage, we will write a simple class with a constructor, and a method that will print Hello World!. Below it will also print whatever message you desire.

class MyClass:

    message = None

    def __init__(self, message=None):
        self.message = message

    def hello_world(self):
        print("Hello World!")
        print(self.message)

Setup.py


Purpose of the setup.py file is to configure the pip package.  It should contain basic information about the package, and calls the setuptools.setup() like the following:

import setuptools

setuptools.setup(
    name="inkipackage",
    version="0.0.1",
    author="ihong5",
    author_email="ihong3589@gmail.com",
    description="just a dummy python package",
    long_description_content_type="text/markdown",
    url="https://github.com/ihong5/inkipackage",
    packages=setuptools.find_packages(),
    classifiers=(
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ),
)

Building Distributable and Locally Installing pip Package


Change directory to base directory of pip package.  Now we are ready to locally install the package, so it can be imported in other Python projects:

Python2 Users:
$ sudo pip install .

Python3 Users:
$ sudo pip3 install .

Using IDLE, try importing the MyClass and call the hello_world() method.
>>> from inkipackage.module import MyClass
>>> myclass = MyClass("Hello visitors!")
>>> myclass.hello_world()
Hello World!
Hello visitors!
>>>

Build the distributable (and later uploadable) package


Python2 Users:
$ sudo python setup.py sdist bdist_wheel

Python3 Users:
$ sudo python3 setup.py sdist bdist_wheel

Uploading pip Package to PyPI


If you have not registered at PyPI already, do so at the PyPI website.

Uploading a Test pip Package


Python2 Users:
$ sudo python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*

Python3 Users:
$ sudo python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*

Once you are happy with the test pip package, then you can proceed to uploading a distributable package as follows:


Uploading a pip Package


Python2 Users:
$ sudo python -m twine upload dist/*

Python2 Users:
$ sudo python3 -m twine upload dist/*