How to publish Python packages on PyPI.
~/.pypirc
and a setup.py
for your project (examples below).twine
.1.0.0-rc-1
, 1.0.0-rc-2
,
and delete these versions afterwards before announcing 1.0.0
.~/.pypirc
[distutils]
index-servers=
pypi
pypitest
[pypi]
username = ...
password = ...
[pypitest]
repository = https://test.pypi.org/legacy/
username = ...
password = ...
$ python setup.py sdist
$ twine upload dist/* -r pypitest
Once you are done with this step test to pip install from https://test.pypi.org:
$ pip install --index-url https://test.pypi.org/simple/ your-package
$ python setup.py sdist bdist_wheel --universal
$ twine upload dist/* -r pypi
Run setup.py
with sdist
to build a source distribution and bdist_wheel
to build a wheel (with --universal
flag if your package is Python 2/3 universal). Then remove old versions from /project/dist/
and ultimately use twine
to upload to pypi.
To tag your current commit as a released version, run:
git tag -a v1.0.0 -m "annotation for this release"
git push origin --tags
Python files not located in a submodule (i.e. a directory with an
__init__.py
) or other files (not a .py
file) can be included via a
MANIFEST.in
file with one of two directives:
include
- used for single files or globbing files from a directory with *
recursive-include
- used for recursively adding files under a directoryAfter creating MANIFEST.in
in your package directory add include_package_data=True
to the setup
object in setup.py
(see below).
MANIFEST.in
include doc/source/*rst
recursive-include project_name/data *
setup.py
from setuptools import setup
import os
import sys
if sys.version_info[0] < 3:
with open('README.rst') as f:
long_description = f.read()
else:
with open('README.rst', encoding='utf-8') as f:
long_description = f.read()
version = {}
with open(os.path.join('numerov', 'version.py')) as f:
exec(f.read(), version)
setup(
name='numerov',
version=version['__version__'],
description='Compute vibrational levels, wavefunctions, and expectation values using the Numerov-Cooley algorithm.',
long_description=long_description,
author='Radovan Bast',
author_email='[email protected]',
url='https://github.com/bast/numerov',
license='MPL-2.0',
packages=['numerov'],
install_requires=[
'click==6.7',
'numpy==1.13.1',
'pyyaml==3.12',
],
scripts=['bin/cooley'],
include_package_data=True,
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Science/Research',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.6',
],
)
You can use the setuptools
function find_packages()
to automatically detect all subpackages and submodules, so long as they contain and __init__.py
file.
from setuptools import setup, find_packages
setup(
#...
packages=find_packages(),
)
If you wish to use README.md
instead of README.rst
, specify long_description_content_type='text/markdown'
in setup.py
.
For automating the creation of setup.py
files, see the documentation for
setup.cfg
.
Thanks to Ryan for showing me the ropes.