Build-time version metadata injection for Python packages. Every artifact is stamped with its version, quality tier, commit SHA, and build date — with no metadata drift between source and installed packages, and no git required at runtime.
| Environment | Version source |
|---|---|
| Git checkout / editable install | Live: git rev-parse + VERSION file |
Installed artifact (no .git) |
Baked: _build.json written at build time |
The quality tier (dev / rc / stable) is controlled by the RELEASE_TYPE
environment variable at build time, so no tag ceremony is needed and no branch
names leak into artifacts.
1. Configure pyproject.toml:
[project]
dynamic = ["version"]
[tool.setuptools.dynamic]
version = {file = "VERSION"}
[tool.setuptools.package-data]
your_package = ["_build.json"]
[build-system]
requires = ["setuptools>=64.0", "wheel", "buildstamp"]
build-backend = "buildstamp.backend"Optional buildstamp configuration:
[tool.buildstamp]
metadata-file = "your_package/_build.json"
version-file = "VERSION"For dev artifact naming, use an environment variable instead of pyproject:
BUILDSTAMP_DEV_VERSION="{base}+g{sha}" RELEASE_TYPE=dev uv buildNo _build_backend.py shim or extra backend-path is required.
3. Add _build.json to .gitignore:
your_package/_build.json
4. Use in your_package/__init__.py:
from buildstamp import load_metadata
_meta = load_metadata(__file__)
__version__ = _meta.version
__quality__ = _meta.quality
__commit__ = _meta.commit
__build_date__ = _meta.build_date5. Create a VERSION file at the project root:
1.0.0
| Field | Type | Dev (checkout) | Artifact |
|---|---|---|---|
version |
str |
"1.0.0+g701e4ca" |
"1.0.0" |
quality |
str |
"dev" |
RELEASE_TYPE value |
commit |
str |
short SHA | short SHA baked at build time |
build_date |
datetime | None |
None |
UTC datetime |
build_date_local |
datetime | None |
None |
local timezone datetime |
To verify the baked metadata in a release artifact without relying on runtime imports:
- Build the artifact:
RELEASE_TYPE=stable uv build --no-build-isolation- List the wheel contents and confirm
_build.jsonis present:
unzip -l dist/buildstamp-*.whl | grep '_build.json'- Extract and pretty-print
_build.jsonfrom the wheel:
unzip -p dist/buildstamp-*.whl buildstamp/_build.json | python -m json.tool- Optionally inspect the source distribution as well:
tar -tzf dist/buildstamp-*.tar.gz | grep 'buildstamp/_build.json'
tar -xOzf dist/buildstamp-*.tar.gz buildstamp/_build.json | python -m json.tool- Convert the stored UTC build timestamp to Amsterdam time:
python - <<'PY'
from datetime import datetime
from zoneinfo import ZoneInfo
utc_dt = datetime.fromisoformat('2026-04-11T21:43:17.362671+00:00')
print(utc_dt.astimezone(ZoneInfo('Europe/Amsterdam')).isoformat())
PY- Verify the artifact format:
uv run twine check dist/*That gives you a fully manual inspection path: the wheel is just a zip archive, _build.json is extracted directly, and the UTC build timestamp can be converted to local display time.
If you want to exercise the baked metadata path from inside a git checkout, first generate _build.json and keep it in the repo:
BUILDSTAMP_FORCE_WRITE=1 uv build --no-build-isolationThen run Python with the baked-metadata override:
BUILDSTAMP_USE_BUILD_JSON=1 python - <<'PY'
from buildstamp import load_metadata
import buildstamp
meta = load_metadata(buildstamp.__file__)
print(meta)
PYBUILDSTAMP_USE_BUILD_JSON is the name to use for in-repo baked metadata testing.
That lets you verify the same _build.json-based runtime behavior without leaving the checkout.
To verify the same baked metadata from an installed package, install the wheel into a fresh environment and use load_metadata():
pip install dist/buildstamp-*.whl
python - <<'PY'
from buildstamp import load_metadata
import buildstamp
meta = load_metadata(buildstamp.__file__)
print('version:', meta.version)
print('quality:', meta.quality)
print('commit:', meta.commit)
print('build_date:', meta.build_date)
print('local build_date:', meta.build_date_local)
PYIf you run this inside the source checkout with .git present, load_metadata() will use live git metadata instead of the baked _build.json. That is why installing the wheel into a clean environment is the right way to verify the shipped artifact.
# stable release
RELEASE_TYPE=stable uv build
# release candidate
RELEASE_TYPE=rc uv buildIf RELEASE_TYPE is unset, the baked quality defaults to "dev".
pip install buildstampWhile not yet on PyPI, install from source:
uv pip install setuptools
uv pip install -e /path/to/buildstamp
uv pip install -e . --no-build-isolationSee VERSIONING.md for the full rationale — including why this avoids git tags, dirty flags, and branch names as version sources.