Hatchling build hook¶
Use this when you build wheels with Hatchling and want an SBOM embedded automatically -- no separate CLI step to remember.
Pitloom embeds the SBOM at
.dist-info/sboms/<name>-<version>.spdx3.json (e.g.
.dist-info/sboms/mypackage-1.0.0.spdx3.json), per PEP 770 (wheels
only), as compact canonical JSON.
Quick guide¶
[build-system]
requires = ["hatchling>=1.29.0", "pitloom>=0.20.2"]
build-backend = "hatchling.build"
[tool.hatch.build.hooks.pitloom]
# This can be empty
That's all -- hatch build and python -m build now embed the SBOM.
Installation¶
Add pitloom as a build requirement (Hatchling 1.29.0+ required) and
add the [tool.hatch.build.hooks.pitloom] table to pyproject.toml
(as shown above) -- both parts are required. Listing pitloom under
[build-system] requires alone does not activate the hook: Hatchling
only runs hooks whose name appears under [tool.hatch.build.hooks], so
the table itself is what turns it on, even left empty.
No separate pip install step is needed beyond that -- the build
front-end (pip, build, hatch) installs pitloom as a build-time
dependency automatically, the same way it installs Hatchling itself.
[!NOTE] Hatchling 1.32.3 changed the build-hook plugin interface, and 1.32.4 reverted the change. Pitloom works with both, but other build-hook plugins written for the usual interface may fail to import on 1.32.3. If you pin Hatchling, prefer any version other than 1.32.3.
Usage details¶
Every hatch build/python -m build invocation now:
- Generates a Build SBOM (
software_SbomType.build) for the project being built. - Merges in any fragments registered under
[tool.pitloom.fragment](see the Python API tracking decorator, or a hand-authored fragment). - Embeds the result into the wheel's
.dist-info/sboms/directory.
[!NOTE] Lock-file resolution and lock-file SHA-256 hash preservation are source-stage only (
loom project/loom generate). Wheels built viahatch builddo not consult source-stage lock files; dependency integrity hashes in embedded build SBOMs are resolved via PyPI (when online) or omitted (when offline).
The table's enabled key defaults to true, so an empty
[tool.hatch.build.hooks.pitloom] is enough. Set enabled = false
inside it to skip generation for a particular build without removing
the table.
Status/skip/deviation messages the hook logs during a build follow the
same grep-able INFO:/WARNING:/ERROR: stderr convention as the
loom CLI (see Command line) -- e.g. a merge failure (see
Merge fragments) fails the build outright
with an ERROR: line, and "generation skipped: hook disabled" is an
INFO:.
Configuration¶
Basename and fragments are configured under [tool.pitloom]:
[tool.pitloom]
sbom-basename = "custom-bom" # -> "custom-bom.spdx3.json" (default: "<name>-<version>")
# (a trailing ".spdx3.json" is dropped, with a WARNING)
[tool.pitloom.fragment]
files = ["fragments/model.json"] # merge externally tracked fragments
Creator/tool metadata uses the same [[tool.pitloom.creator]] /
[[tool.pitloom.creation-tool]] / [tool.pitloom.creation] tables the
CLI reads -- see Creation metadata. Provenance
detail is controlled the same way too -- see Metadata
provenance.
See also¶
- Command line -- generate an SBOM manually or post-process built
wheels with
loom embed-wheel. - Dependency sources and precedence -- why wheel embedding scopes dependencies to the build stage.
- GitHub Action -- embed PEP 770 SBOMs in CI for any build backend.
- Python API -- the tracking decorator that produces the fragments this hook merges.