how to upload python package to pypi

how to upload python package to pypi

Python is a open-source programming language. It's very easy to learn and use. It is used in many areas like web development, game development, network programming, scientific and numeric computing and more. Python's license is administered by the Python Software Foundation. As it is a open-source so many developers are writing their own packages for reusability. Instead of writing the same functionality again we can use the package that is developed by other developers. It saves time and development cost. As it is an open-source, it won't cost any charge. PyPI is the software foundation which manages the all python packages which were developed by open-source contributors. In this article we will see how to upload your python package to PyPI .

Steps to upload a python package to PyPI.

  1. Create a project directory. The project directory can of any name of your choice.
  2. After creating the project directory create files LICENSE.txt, MANIFEST.in, README.rst, setup.py and create a directory with package name that will be used in imports.
  3. Create another directory named "docs" which will contain documentation of our python package.
  4. After finishing the above steps, our poject structure looks like below
PROJECT-DIRECTORY
├── LICENSE.txt
├── MANIFEST.in
├── README.rst
├── docs (FOLDER)
├── setup.py
└── PACKAGENAME (FOLDER)
    ├── __init__.py
    ├── file1.py
    └── file2.py
  1. Let's see descriptions for above files.

    • LICENSE.txt: The license that we use to release our python package. It looks something like
    The main hap.py code (in the src subfolder) is distributed under the
    simplified BSD license.
    
    -------------------------------------------------------------------------------
    Copyright (c) 2018 Learnbatta.com.
    All rights reserved.
    
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    
    1. Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
    
    2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    • MANIFEST.in: When "setup.py" builds our python package, it includes "*.py" files in our package. If we want other files to be included in the .tar.gz file that will be uploaded to PyPI then we add these files in "MANIFEST.in" file. It is something looks like
    include README.rst
    recursive-include docs/*
    
    • README.rst: It contains the documentation of the project/package. Please see example.

    • setup.py: It is the magic file that create and installs our python package. It also keeps that track of version and formatting for PyPI. The python packages that used in writing the "setup.py" is "distutils" and "setuptools". The sample setup.py looks something like

    # -*- coding: utf-8 -*-
    import os
    import sys
    from distutils.core import setup
    
    CURRENT_PYTHON = sys.version_info[:2]
    REQUIRED_PYTHON = (3, 5)
    
    
    def read(fname):
        return open(os.path.join(os.path.dirname(__file__), fname)).read()
    
    
    if CURRENT_PYTHON < REQUIRED_PYTHON:
        sys.stderr.write("This version of Pydicttoxml requires Python {}.{},\
            but you're trying to install it on Python {}.{}.".format(
            *(REQUIRED_PYTHON + CURRENT_PYTHON)))
        sys.exit(1)
    setup(
        name='pydicttoxml',
        version='1.0.1',
        description='Convert python dictionary into a xml equivalent format',
        author=u'Anjaneyulu Batta',
        author_email='[email protected]',
        url='https://github.com/AnjaneyuluBatta505/pydicttoxml',
        packages=['pydicttoxml'],
        keywords="convert dictionary into a xml",
        long_description=read('README.rst'),
        classifiers=[
            'Intended Audience :: Developers',
            'License :: OSI Approved :: MIT License',
            'Operating System :: OS Independent',
            'Programming Language :: Python',
            'Programming Language :: Python :: 3.5',
            'Programming Language :: Python :: 3.6',
            'Topic :: Software Development :: Libraries :: Python Modules',
            'Topic :: Text Processing :: Markup :: XML'
        ],
        license='MIT'
    )
    
    • Let's try to understand a bit about parameters passed to setup function in above file.
      • name: The name will be used while installing the python package via pip
      • version: Version of currently releasing python package
      • description: Short description of python package
      • author: Author name of the python package
      • author_email: Author contact email of the python package
      • url: Url to the repository where the code resides.
      • packages: Python packages that will we added to tar.gz file while archiving the python package.
      • keywords: Keywords that will be used to search for that package in the search engines like google, bing and yahoo, etc.
      • long_description: It contains the information of package how it can be used. It contains the complete description.
      • classifiers: classifiers can then be used by community members to find projects based on their desired criteria. For more info visit https://pypi.org/classifiers/
      • licence: under which license our package is releasing.
  2. When we are ready with everything mentioned above then we are ready to go. Before that we need to have an account in the pypi.org.

    • Go to our project directory in Terminal(Ubuntu).Install required packages "setuptools", "distutils" and "twine" with pip

    pip install setuptools
    pip install distutils
    pip install twine
    
    - Now, create our python package distribution with below command.
    python setup.py sdist
    
    - After executing the above command it will create a "tar.gz" file inside the directoy "project/sdist/<package-version>.tar.gz"

  3. Before uploading our very first python package lets create a configuration file "~/.pypirc" and add configuration details. The file looks something like

[distutils]
index-servers =
    pypi
[pypi]
username: {username}
password:{password}
  1. Upload our python package to pypi with below command
twine upload dist/PACKAGENAME-VERSION.tar.gz
  1. Now, test our package by installing it via pip
pip install {package name}

It will work as we expected if not let me help you. If you get any errors then we will discuss in comment section below.

References: