Building Artifacts¶
How beetkeeper's build artifacts are produced with Pants. All commands run from the repo root.
| Artifact | Pants target | Notes |
|---|---|---|
beetkeeper wheel |
src/python:beetkeeper-whl |
pure-python, py3-none-any |
beetkeeper-plugin wheel |
src/beetsplug:plugin-whl |
pure-python |
| image PEXes | //:beetkeeper-linux-amd64, //:beetkeeper-linux-arm64 |
thin, single-arch; bundled into the image |
| server image | //:beetkeeper-server-image |
GHCR (db upgrade / run) |
pants package //:beetkeeper-server-image # builds the host-arch image (+ its PEX)
pants package src/python:beetkeeper-whl
The image PEXes (//:beetkeeper-linux-<arch>)¶
The Docker image bundles a thin, single-arch PEX built for its target Linux arch. Each is a pex_binary
pinned via complete_platforms to one platform (linux-amd64 or linux-aarch64), so it carries only
that arch's native wheels (e.g. llvmlite, pulled in via beets → numba). complete_platforms lets PEX
resolve those foreign wheels locally — on a macOS dev machine or a native CI runner — without a foreign
interpreter or emulator, so the same pants package works everywhere. The Dockerfile's ARG TARGETARCH
selects the matching PEX at COPY time.
A complete platform is a JSON description of a target interpreter — its PEP 508 marker environment plus
the full list of wheel tags it accepts — stored under 3rdparty/platforms/.
Only
linux-amd64/linux-aarch64are targeted — the images are Linux-only. Themusl-linux-*(Alpine) JSONs are kept for reference but unused:numba/llvmliteship no cp314 musl wheel.
Regenerating the complete-platform JSONs¶
Regenerate whenever the target interpreter version changes (e.g. a Python minor bump). The files are
tied to a specific cp314 interpreter; do not hand-edit or hand-copy subsets — a truncated tag list
silently drops generic tags like py3-none-any and breaks pure-python wheel resolution.
The generator is pex3 interpreter inspect --markers --tags, run once per target. Its raw output includes
a machine-specific path key that must be stripped; the jq filter below drops it and prepends the
__meta_data__ note. Repeat steps 1–2 for each SLUG (linux-amd64, linux-aarch64).
- Generate the interpreter inspection inside a matching-architecture
python:3.14-slimcontainer — the non-native arch runs under QEMU on an Apple-silicon host: - Strip
pathand write the committed file: - Rebuild and confirm the arch's native
llvmlitewheel is bundled:
FAQ¶
The JSON files list py38-* and cp310-* tags — does the PEX run on Python 3.8 / 3.10?
No. compatible_tags lists the wheels a cp314 interpreter is willing to install, ordered by
preference — not interpreters that can run the PEX. The list runs downward for backward compatibility:
py38-none-* / py3-none-any are pure-Python wheels (a "3.8+, no C" wheel also runs on 3.14), and
cp310-abi3-* are stable-ABI wheels (abi3 is forward-compatible, so a 3.10-ABI extension loads on 3.14).
Note the files contain only cp310-abi3, never cp310-cp310 — a genuine 3.10-only binary wheel is not
accepted. The actual runtime floor is 3.14, pinned by the JSON's marker_environment.python_full_version
and the target's interpreter_constraints = [">=3.14,<3.15"] (pants.toml); the PEX rejects a 3.8/3.10
interpreter at launch. The older tags simply let the 3.14 build reuse older pure-python/abi3 wheels when no
cp314-specific wheel exists — which is exactly why the full tag list matters (drop py3-none-any and
pure-python deps like aiosqlite stop resolving).
Why not one fat multi-platform PEX for all arches?
A single PEX bundling every arch's wheels would carry ~100 MB of foreign-platform llvmlite/numba that a
fixed-arch container can never use. Since each image is one arch, a per-arch PEX is strictly smaller. The
complete_platforms mechanism could produce a fat PEX (list all platforms on one pex_binary), but nothing
consumes one today.
With execution_mode="venv", does the PEX pick up libraries from the virtualenv it's invoked from?
No. venv mode is an internal startup optimization: on first run PEX materializes its own bundled
distributions into a private venv under PEX_ROOT and re-execs into it for faster imports. It does not see
the ambient environment's site-packages. PEXes are hermetic by default. Ambient-library visibility is a
separate knob — inherit_path (PEX_INHERIT_PATH): false (default, isolated), fallback (PEX wins,
ambient fills gaps), or prefer (ambient wins). The image PEXes set inherit_path="fallback" so a derived
image can pip install an extra beets plugin and have the PEX pick it up.
Generating OpenAPI Spec JSON¶
To regenerate the OpenAPI spec JSON for the user reference site, run the following command: