Submit your Python library to PyPI (Python Package Index)

Packaging and Distributing Projects
https://packaging.python.org/distributing/

A Human's Ultimate Guide to setup.py
https://github.com/kennethreitz/setup.py

Sharing Your Labor of Love: PyPI Quick and Dirty
https://hynek.me/articles/sharing-your-labor-of-love-pypi-quick-and-dirty/

setup.py Example

#!/usr/bin/env python
# coding: utf-8

import os
import sys

from setuptools import find_packages
from setuptools import setup

def get_version():
    code = None
    path = os.path.join(
        os.path.dirname(os.path.abspath(__file__)),
        'jokekappa',
        '__init__.py',
    )
    with open(path) as f:
        for line in f:
            if line.startswith('__version__'):
                code = line[len('__version__ = '):]
                break
    return eval(code)

if sys.argv[-1] == 'wheel':
    os.system('rm -rf dist/*')
    os.system('pip install wheel')
    os.system('python setup.py bdist_wheel')
    sys.exit(0)

if sys.argv[-1] == 'publish':
    os.system('python setup.py wheel')
    os.system('pip install twine')
    os.system('twine upload dist/*')
    sys.exit(0)

long_description = open('README.rst').read()

requirements_lines = [line.strip() for line in open('requirements.txt').readlines()]
install_requires = list(filter(None, requirements_lines))

setup(
    name='jokekappa',
    version=get_version(),
    url='https://github.com/CodeTengu/jokekappa',
    description='A library for delivering one-line programming jokes.',
    long_description=long_description,
    keywords='jokes programming-jokes',
    author='Vinta Chen',
    author_email='[email protected]',
    license='MIT',
    install_requires=install_requires,
    scripts=['scripts/jokekappa', ],
    packages=find_packages(exclude=('tests', )),
    include_package_data=True,
    test_suite='tests',
    classifiers=(
        'Development Status :: 3 - Alpha',
        'Environment :: Console',
        'Environment :: Web Environment',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Natural Language :: English',
        'Natural Language :: Chinese (Simplified)',
        'Natural Language :: Chinese (Traditional)',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Topic :: Software Development :: Libraries :: Python Modules',
        'Topic :: Utilities',
    ),
)

ref:
https://github.com/pypa/twine/blob/master/setup.py
https://packaging.python.org/distributing/#configuring-your-project
https://pypi.python.org/pypi?%3Aaction=list_classifiers

If you have exactly one Python file, for instance: pangu.py, use py_modules instead of packages in setup.py:

py_modules=['pangu', ],

ref:
https://docs.python.org/2/distutils/examples.html#pure-python-distribution-by-package

setuptools.find_packages() finds *.py files only, you're able to set include_package_data=True for including requirements.txt or *.html files. Additionally, you may specify extra files to include or exclude in MANIFEST.in:

recursive-include jokekappa/jokes *.json
include LICENSE
include README.rst
include requirements.txt

.pypirc Example

in ~/.pypirc

[pypi]
username=YOUR_USERNAME
password=YOUR_PASSWORD

ref:
https://packaging.python.org/distributing/#create-an-account

Commands

You need to register an account on Python Package Index to submit your package.

$ pip install -U pip setuptools wheel twine

$ python setup.py --help
$ python setup.py --help-commands 

# install locally
$ python setup.py install

# link your package files to site-packages, for debug
$ python setup.py develop

# you must specify `test_suite` in `setup.py`
$ python setup.py test

# pack in wheel format
$ python setup.py bdist_wheel

# pack in the traditional way
$ python setup.py sdist

# upload
$ twine upload dist/*

ref:
https://packaging.python.org/distributing/#upload-your-distributions
https://github.com/pypa/twine