{"id":5,"date":"2014-02-14T12:37:04","date_gmt":"2014-02-14T04:37:04","guid":{"rendered":"http:\/\/vinta.ws\/code\/?p=5"},"modified":"2026-02-18T01:20:37","modified_gmt":"2026-02-17T17:20:37","slug":"submit-to-pypi-python-package-index","status":"publish","type":"post","link":"https:\/\/vinta.ws\/code\/submit-to-pypi-python-package-index.html","title":{"rendered":"Submit your Python Library to PyPI (Python Package Index)"},"content":{"rendered":"<p>Packaging Python Projects<br \/>\n<a href=\"https:\/\/packaging.python.org\/tutorials\/packaging-projects\/\">https:\/\/packaging.python.org\/tutorials\/packaging-projects\/<\/a><\/p>\n<p>A Human's Ultimate Guide to setup.py<br \/>\n<a href=\"https:\/\/github.com\/kennethreitz\/setup.py\">https:\/\/github.com\/kennethreitz\/setup.py<\/a><\/p>\n<p>Sharing Your Labor of Love: PyPI Quick and Dirty<br \/>\n<a href=\"https:\/\/hynek.me\/articles\/sharing-your-labor-of-love-pypi-quick-and-dirty\/\">https:\/\/hynek.me\/articles\/sharing-your-labor-of-love-pypi-quick-and-dirty\/<\/a><\/p>\n<h2>setup.py Example<\/h2>\n<pre class=\"line-numbers\"><code class=\"language-py\">#!\/usr\/bin\/env python\n# coding: utf-8\n\nimport os\nimport sys\n\nfrom setuptools import find_packages\nfrom setuptools import setup\n\ndef get_version():\n    code = None\n    path = os.path.join(\n        os.path.dirname(os.path.abspath(__file__)),\n        'jokekappa',\n        '__init__.py',\n    )\n    with open(path) as f:\n        for line in f:\n            if line.startswith('__version__'):\n                code = line[len('__version__ = '):]\n                break\n    return eval(code)\n\nif sys.argv[-1] == 'wheel':\n    os.system('rm -rf dist\/*')\n    os.system('pip install wheel')\n    os.system('python setup.py bdist_wheel')\n    sys.exit(0)\n\nif sys.argv[-1] == 'publish':\n    os.system('python setup.py wheel')\n    os.system('pip install twine')\n    os.system('twine upload dist\/*')\n    sys.exit(0)\n\nlong_description = open('README.rst').read()\n\nrequirements_lines = [line.strip() for line in open('requirements.txt').readlines()]\ninstall_requires = list(filter(None, requirements_lines))\n\nsetup(\n    name='jokekappa',\n    version=get_version(),\n    url='https:\/\/github.com\/CodeTengu\/jokekappa',\n    description='A library for delivering one-line programming jokes.',\n    long_description=long_description,\n    keywords='jokes programming-jokes',\n    author='Vinta Chen',\n    author_email='vinta.chen@gmail.com',\n    license='MIT',\n    install_requires=install_requires,\n    scripts=['scripts\/jokekappa', ],\n    packages=find_packages(exclude=('tests', )),\n    include_package_data=True,\n    test_suite='tests',\n    classifiers=(\n        'Development Status :: 3 - Alpha',\n        'Environment :: Console',\n        'Environment :: Web Environment',\n        'Intended Audience :: Developers',\n        'License :: OSI Approved :: MIT License',\n        'Natural Language :: English',\n        'Natural Language :: Chinese (Simplified)',\n        'Natural Language :: Chinese (Traditional)',\n        'Operating System :: OS Independent',\n        'Programming Language :: Python',\n        'Programming Language :: Python :: 2',\n        'Programming Language :: Python :: 2.7',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Python :: 3.3',\n        'Programming Language :: Python :: 3.4',\n        'Programming Language :: Python :: 3.5',\n        'Programming Language :: Python :: 3.6',\n        'Topic :: Software Development :: Libraries :: Python Modules',\n        'Topic :: Utilities',\n    ),\n)<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/github.com\/pypa\/twine\/blob\/master\/setup.py\">https:\/\/github.com\/pypa\/twine\/blob\/master\/setup.py<\/a><br \/>\n<a href=\"https:\/\/pypi.python.org\/pypi?%3Aaction=list_classifiers\">https:\/\/pypi.python.org\/pypi?%3Aaction=list_classifiers<\/a><\/p>\n<p>If you have exactly one Python file, for instance: <code>pangu.py<\/code>, use <code>py_modules<\/code> instead of <code>packages<\/code> in <code>setup.py<\/code>:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-py\">py_modules=['pangu', ],<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/docs.python.org\/2\/distutils\/examples.html#pure-python-distribution-by-package\">https:\/\/docs.python.org\/2\/distutils\/examples.html#pure-python-distribution-by-package<\/a><\/p>\n<p><code>setuptools.find_packages()<\/code> finds <code>*.py<\/code> files only, you're able to set <code>include_package_data=True<\/code> for including <code>requirements.txt<\/code> or <code>*.html<\/code> files. Additionally, you may specify extra files to include or exclude in <code>MANIFEST.in<\/code>:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-properties\">recursive-include jokekappa\/jokes *.json\ninclude LICENSE\ninclude README.rst\ninclude requirements.txt<\/code><\/pre>\n<h2>.pypirc Example<\/h2>\n<p>in ~\/.pypirc<\/p>\n<pre class=\"line-numbers\"><code class=\"language-ini\">[pypi]\nusername=YOUR_USERNAME\npassword=YOUR_PASSWORD<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/pypi.org\/account\/register\/\">https:\/\/pypi.org\/account\/register\/<\/a><\/p>\n<h2>Commands<\/h2>\n<p>You need to register an account on Python Package Index to submit your package.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-console\">$ pip install -U pip setuptools wheel twine\n\n$ python setup.py --help\n$ python setup.py --help-commands \n\n# install locally\n$ python setup.py install\n\n# link your package files to site-packages, for debug\n$ python setup.py develop\n\n# you must specify <code>test_suite<\/code> in <code>setup.py<\/code>\n$ python setup.py test\n\n# pack in wheel format\n$ python setup.py bdist_wheel\n\n# pack in the traditional way\n$ python setup.py sdist\n\n# upload\n$ twine upload dist\/*<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/packaging.python.org\/tutorials\/packaging-projects\/#uploading-the-distribution-archives\">https:\/\/packaging.python.org\/tutorials\/packaging-projects\/#uploading-the-distribution-archives<\/a><br \/>\n<a href=\"https:\/\/github.com\/pypa\/twine\">https:\/\/github.com\/pypa\/twine<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sharing your Python Packages on PyPI!<\/p>\n","protected":false},"author":1,"featured_media":495,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[2],"class_list":["post-5","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-about-python","tag-python"],"_links":{"self":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/5","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/comments?post=5"}],"version-history":[{"count":0,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/5\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media\/495"}],"wp:attachment":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media?parent=5"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/categories?post=5"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/tags?post=5"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}