Creating a package
How to create a package for pip
To create a distribution package, additional files beyond the implementation are needed. It is recommended to have a project directory named after the package, with implementation files and directories in a subdirectory src
.
Modern Python packaging is based on a pyproject.toml
file in the project directory.
Defining metadata
Metadata are provided in a TOML ‘table’ project
:
[project]
Name of the distribution package. To avoid being changed by normalization, it should be lowercase and contain only
a
–z
,0
–9
, and-
.name = "mkernel"
Version in the format of PEP 440. It can also be extracted from the implementation files, see below.
version = "1.0.0"
A one-line description. Could include a different stylization of the package name.
description = "MKernel: A Jupyter Kernel for Matlab"
Pointer to a README file in the same directory. Markdown (
.md
) and ReStructuredText (.rst
) are automatically recognized.readme = "README.md"
Required version of Python. Should at least specify whether Python 2 or 3.
requires-python = ">=3.3"
Names of authors. Emails can be specified with an additional key
email
.authors = [{name = "Carsten Allefeld"}]
If separate from authors, there can be an additional entry
maintainers
.Freely chosen keywords characterizing the package.
keywords = ["jupyter", "kernel", "matlab"]
Classifiers characterizing the project, from a defined list.
classifiers = [ "Development Status :: 5 - Production/Stable", "Framework :: Jupyter", "Intended Audience :: Science/Research", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering" ]
Packages this package depends on, specified according to PEP 508.
dependencies = [ "ipykernel", "matlabengine", "wurlitzer" ]
URLs where further information can be found, as a sub-table. Normally
Homepage
is sufficient, but separate entries forDocumentation
,Repository
, andChangelog
are also supported.[project.urls] Homepage = "https://github.com/allefeld/mkernel"
In addition it is possible
- to point to a LICENSE file, but that is somewhat redundant with
classifiers
, - to include optional dependencies,
- and to define entry points for command line and GUI scripts.
Additional features depending on a build backend
We here use hatchling.build
, which has to be configured via the build-system
table:
requires = ["hatchling"]
build-backend = "hatchling.build"
Version information can be obtained from the implementation files. To do so, replace
version = "1.0.0"
bydynamic = ["version"]
and add
[tool.hatch.version] path = "src/mkernel/kernel.py"
where the specified file has to contain a line of the form
__version__ = '1.0.0'
.Non-implementation files (wheel subdirectory
{distribution}-{version}.data/
) can be included in the package, e.g. a Jupyter kernel specification.[tool.hatch.build.targets.wheel.shared-data] "kernelspec/kernel.json" = "share/jupyter/kernels/mkernel/kernel.json"
The entries of this table map paths within the project directory to paths within
{distribution}-{version}.data/data/
, i.e. the data files part of the install scheme.
See also OS Integration Files in Python Packages.
Building
The simplest way to build the package into a wheel file is to run from the project directory:
pip wheel --no-deps .
It is also implicitly built when installing from source (either a local directory or a git repository).
How to create a package for conda
TODO