Packages#
All our packages should be distributed on PyPI.
Use the Pypackage Cookiecutter template:
pip install cookiecutter
cookiecutter gh:open-contracting/software-development-handbook --directory cookiecutter-pypackage
See also
Package-rated content in Directory layout, Testing and Linting
Metadata#
If the package is distributed on PyPI, use this template for the setup.cfg
file, adding options like entry_points
and namespace_packages
as needed, and removing the Jinja syntax if not using the Cookiecutter template:
[flake8]
max-line-length = 119
extend-ignore = E203
[metadata]
name = {{ cookiecutter.package_name }}
version = 0.0.1
author = Open Contracting Partnership
author_email = data@open-contracting.org
license = BSD
description = {{ cookiecutter.short_description }}
url = https://github.com/open-contracting/{{ cookiecutter.repository_name }}
long_description = file: README.rst
long_description_content_type = text/x-rst
classifiers =
License :: OSI Approved :: BSD License
{%- if cookiecutter.os_independent == "y" %}
Operating System :: OS Independent
{%- else %}
Operating System :: POSIX :: Linux
{%- endif %}
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: Implementation :: CPython
{%- if cookiecutter.pypy == "y" %}
Programming Language :: Python :: Implementation :: PyPy
{%- endif %}
[options]
packages = find:
install_requires =
[options.packages.find]
exclude =
tests
tests.*
[options.extras_require]
test =
coveralls
pytest
pytest-cov
docs =
furo
sphinx
sphinx-autobuild
If the package isn’t distributed on PyPI, use this template setup.cfg
:
[metadata]
name = NAME
version = 0.0.0
license = BSD
[options]
packages = find:
install_requires =
REQUIREMENT
Reference: Packaging and distributing projects
Requirements#
Use
install_requires
andextras_require
in thesetup.cfg
fileDo not use a
requirements.txt
fileSort requirements alphabetically
See also
Classifiers#
"Operating System :: OS Independent"
The package is tested on macOS, Windows and Ubuntu.
"Operating System :: POSIX :: Linux"
The package is tested on Ubuntu only.
"Programming Language :: Python :: Implementation :: PyPy"
The package is tested on PyPy.
Documentation#
The template reads the documentation from a README.rst
file. To convert a README.md
file, install pandoc
and run:
pandoc --from=markdown --to=rst --output=README.rst README.md
See also
Release process#
One-time setup
To publish tagged releases to PyPI, create a .github/workflows/pypi.yml
file:
name: Publish to PyPI
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: pip install --upgrade build
- run: python -m build --sdist --wheel
- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository_url: https://test.pypi.org/legacy/
skip_existing: true
- name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
The open-contracting organization sets the PYPI_API_TOKEN
organization secret to the API token of the opencontracting PyPI user, and TEST_PYPI_API_TOKEN
to that of the TestPyPI user.
After publishing the first release to PyPI, add additional owners.
Ensure that you are on an up-to-date
main
branch:git checkout main git pull --rebase
Ensure that the package is ready for release:
All tests pass on continuous integration
The version number is correct in
setup.cfg
anddocs/conf.py
(if present)The changelog is up-to-date and dated
Tag the release, replacing
x.y.z
twice:git tag -a x.y.z -m 'x.y.z release.'
Push the release:
git push --follow-tags
Announce on the discussion group if relevant
Reference: Publishing package distribution releases using GitHub Actions CI/CD workflows