Skip to content

Commit 5734dde

Browse files
adding a "packaging flow" overview document (#1100)
* add initial translation of the flow document from the MarkDown original * source/index.rst: add the flow to the toctree * source/flow.rst: minor formatting and typo fixes * flow.rst: some suggestions from @ abravalheri * flow.rst: small clarification that this is about distribution packages, suggestion from @sinoroc * undo previous commit - this isn't just about distribution packages * flow.rst: I was wrong, restoring @sinoroc's suggestion * flow.rst: The Configuration File: be less prescriptive - suggestion by @abravalheri * flow.rst: The Build System: small elaboration suggested by @pfmoore * flow.rst: use :pep: roles for PEP references * flow.rst: convert in tree refs to :doc: * flow.rst: small fixups * Lots of copy edits and TODOs * Set 78 character line length * Condense build-system description * Tweak project links * flow.rst: restore mention of "pip" in the end user steps * flow.rst: no, the PEP links are indeed not useful; I've mentioned a PEP elsewhere in context though * flow.rst: replace tool links with references to the key projects file * flow.rst: mention build frontends and backends * flow.rst: mention all 3 of setuptools, flit and hatchling * flow.rst: add a paragraph about end user systems how wheel tags can denote them * Reformat and add TODOs * Link more key projects * Rework wheel section * Rework frontend and backend * Simplify example build-system * Always use ref for tools * Link other install tools * Tweak pip reference Co-authored-by: Brian Rutledge <[email protected]>
1 parent e785378 commit 5734dde

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

source/flow.rst

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
==================
2+
The Packaging Flow
3+
==================
4+
5+
The document aims to outline the flow involved in publishing/distributing a
6+
:term:`distribution package <Distribution Package>`, usually to the `Python
7+
Package Index (PyPI)`_. It is written for package publishers, who are assumed
8+
to be the package author.
9+
10+
.. _Python Package Index (PyPI): https://pypi.org/
11+
12+
While the :doc:`tutorial <tutorials/packaging-projects>` walks through the
13+
process of preparing a simple package for release, it does not fully enumerate
14+
what steps and files are required, and for what purpose.
15+
16+
Publishing a package requires a flow from the author's source code to an end
17+
user's Python environment. The steps to achieve this are:
18+
19+
- Have a source tree containing the package. This is typically a checkout from
20+
a version control system (VCS).
21+
22+
- Prepare a configuration file describing the package metadata (name, version
23+
and so forth) and how to create the build artifacts. For most packages, this
24+
will be a :file:`pyproject.toml` file, maintained maunally in the source
25+
tree.
26+
27+
- Create build artifacts to be sent to the package distribution service
28+
(usually PyPI); these will normally be a
29+
:term:`source distribution ("sdist") <Source Distribution (or "sdist")>`
30+
and one or more :term:`built distributions ("wheels") <Built Distribution>`.
31+
These are made by a build tool using the configuration file from the
32+
previous step. Often there is just one generic wheel for a pure Python
33+
package.
34+
35+
- Upload the build artifacts to the package distribution service.
36+
37+
At that point, the package is present on the package distribution service.
38+
To use the package, end users must:
39+
40+
- Download one of the package's build artifacts from the package distribution
41+
service.
42+
43+
- Install it in their Python environment, usually in its ``site-packages``
44+
directory. This step may involve a build/compile step which, if needed, must
45+
be described by the package metadata.
46+
47+
These last 2 steps are typically performed by :ref:`pip` when an end user runs
48+
``pip install``.
49+
50+
The steps above are described in more detail below.
51+
52+
The source tree
53+
===============
54+
55+
The source tree contains the package source code, usually a checkout from a
56+
VCS. The particular version of the code used to create the build artifacts
57+
will typically be a checkout based on a tag associated with the version.
58+
59+
The configuration file
60+
======================
61+
62+
The configuration file depends on the tool used to create the build artifacts.
63+
The standard practice is to use a :file:`pyproject.toml` file in the `TOML
64+
format`_.
65+
66+
.. _TOML format: https://github.com/toml-lang/toml
67+
68+
At a minimum, the :file:`pyproject.toml` file needs a ``[build-system]`` table
69+
specifying your build tool. There are many build tools available, including
70+
but not limited to :ref:`flit`, :ref:`hatch`, :ref:`pdm`, :ref:`poetry`,
71+
:ref:`setuptools`, `trampolim`_, and `whey`_. Each tool's documentation will
72+
show what to put in the ``[build-system]`` table.
73+
74+
.. _trampolim: https://pypi.org/project/trampolim/
75+
.. _whey: https://pypi.org/project/whey/
76+
77+
For example, here is a table for using :ref:`hatch`:
78+
79+
.. code-block:: toml
80+
81+
[build-system]
82+
requires = ["hatchling"]
83+
build-backend = "hatchling.build"
84+
85+
With such a table in the :file:`pyproject.toml` file, a "frontend" tool like
86+
:ref:`build` can run your chosen build tool's "backend" to create the build
87+
artifacts. Your build tool may also provide its own frontend. An install tool
88+
like :ref:`pip` also acts as a frontend when it runs your build tool's backend
89+
to install from a source distribution.
90+
91+
The particular build tool you choose dictates what additional information is
92+
required in the :file:`pyproject.toml` file. For example, you might specify:
93+
94+
* a ``[project]`` table containing project
95+
:doc:`Core Metadata </specifications/core-metadata/>`
96+
(name, version, author and so forth); see
97+
:doc:`Declaring project metadata </specifications/declaring-project-metadata/>`
98+
for more detail
99+
100+
* a ``[tool]`` table containing tool-specific configuration options
101+
102+
Build artifacts
103+
===============
104+
105+
The source distribution (sdist)
106+
-------------------------------
107+
108+
A source distribution contains enough to install the package from source in an
109+
end user's Python environment. As such, it needs the package source, and may
110+
also include tests and documentation. These are useful for end users wanting
111+
to develop your sources, and for end user systems where some local compilation
112+
step is required (such as a C extension).
113+
114+
The :ref:`build` package knows how to invoke your build tool to create one of
115+
these:
116+
117+
.. code-block:: bash
118+
119+
python3 -m build --sdist source-tree-directory
120+
121+
Or, your build tool may provide its own interface for creating an sdist.
122+
123+
124+
The built distributions (wheels)
125+
--------------------------------
126+
127+
A built distribution contains only the files needed for an end user's Python
128+
environment. No compilation steps are required during the install, and the
129+
wheel file can simply be unpacked into the ``site-packages`` directory. This
130+
makes the install faster and more convenient for end users.
131+
132+
A pure Python package typically needs only one "generic" wheel. A package with
133+
compiled binary extensions needs a wheel for each supported combination of
134+
Python interprerter, operating system, and CPU architecture that it supports.
135+
If a suitable wheel file is not available, tools like :ref:`pip` will fall
136+
back to installing the source distribtion.
137+
138+
The :ref:`build` package knows how to invoke your build tool to create one of
139+
these:
140+
141+
.. code-block:: bash
142+
143+
python3 -m build --wheel source-tree-directory
144+
145+
Or, your build tool may provide its own interface for creating a wheel.
146+
147+
.. note::
148+
149+
The default behaviour of :ref:`build` is to make both an sdist and a wheel
150+
from the source in the current directory; the above examples are
151+
deliberately specific.
152+
153+
Upload to the package distribution service
154+
==========================================
155+
156+
The :ref:`twine` tool can upload build artifacts to PyPI for distribution,
157+
using a command like:
158+
159+
.. code-block:: bash
160+
161+
twine upload dist/package-name-version.tar.gz dist/package-name-version-py3-none-any.whl
162+
163+
Or, your build tool may provide its own interface for uploading.
164+
165+
Download and install
166+
====================
167+
168+
Now that the package is published, end users can download and install the
169+
package into their Python environment. Typically this is done with :ref:`pip`,
170+
using a command like:
171+
172+
.. code-block:: bash
173+
174+
python3 -m pip install package-name
175+
176+
End users may also use other tools like :ref:`pipenv`, :ref:`poetry`, or
177+
:ref:`pdm`.

source/index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Python Packaging User Guide
1111
:hidden:
1212

1313
overview
14+
flow
1415
tutorials/index
1516
guides/index
1617
discussions/index
@@ -37,6 +38,8 @@ Get started
3738
Essential tools and concepts for working within the Python
3839
development ecosystem are covered in our :doc:`tutorials/index` section:
3940

41+
* To get an overview of the flow used to publish your code, see the
42+
:doc:`packaging flow <flow>`
4043
* To learn how to install packages, see the
4144
:doc:`tutorial on installing packages <tutorials/installing-packages>`
4245
* To learn how to manage dependencies in a version controlled project, see the

0 commit comments

Comments
 (0)