Wheel

A framework for defining wheels from a tree of Bazel targets.

Why use this over what rules_python provides?

The rules here primarily wrap what rules_python provides but offers some improvements:

  1. Requirements are collected from transitive dependencies and added as Require-Dist to the wheel.
  2. Sources and data are automatically collected.

Setup

Building wheels requires no setup, however, to activate all features of the wheel rules, a toolchain must be registered.

First some external python requirements will be required. There is guidance on how to configure this in projects like rules_req_compile. Once there is a means to fetch external dependencies within your repository, a toolchain can be defined in a BUILD.bazel file.

Example //:BUILD.bazel:

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_toolchain")

py_wheel_toolchain(
    name = "py_wheel_toolchain_impl",
    # Definable using bzlmod modules like: https://github.com/periareon/req-compile
    twine = "@pip_deps//:twine",
    visibility = ["//visibility:public"],
)

toolchain(
    name = "py_wheel_toolchain",
    toolchain = ":py_wheel_toolchain_impl",
    toolchain_type = "@rules_venv//python/wheel:toolchain_type",
    visibility = ["//visibility:public"],
)

Once the toolchain is defined, it should be registered in the MODULE.bazel file

Example //:MODULE.bazel:

register_toolchains(
    "//:py_wheel_toolchain",
)

This will ensure all features of the wheel rules are available and usable.

Rules

Functions

py_wheel_publisher

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_publisher")

py_wheel_publisher(name, repository_url, wheel)

A rule for publishing wheels to pypi registries.

The rule uses twine to python registries. Users should refer to the documentation there for any configuration flags (such as auth) needed to deploy to the desired location.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
repository_urlThe repository (package index) URL to upload the wheel to. If passed the twine arg --repository-url will be set to this value.Stringoptional""
wheelThe wheel to extract.Labelrequired

py_wheel_toolchain

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_toolchain")

py_wheel_toolchain(name, twine)

A toolchain for powering the py_wheel rules.

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_toolchain")

py_wheel_toolchain(
    name = "py_wheel_toolchain_impl",
    # Definable using bzlmod modules like: https://github.com/periareon/req-compile
    twine = "@pip_deps//:twine",
    visibility = ["//visibility:public"],
)

toolchain(
    name = "py_wheel_toolchain",
    toolchain = ":py_wheel_toolchain_impl",
    toolchain_type = "@rules_venv//python/wheel:toolchain_type",
    visibility = ["//visibility:public"],
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
twineA py_library for twine.Labelrequired

package_tag

load("@rules_venv//python/wheel:defs.bzl", "package_tag")

package_tag(name)

Generate a tag used to associate the target with a python package.

This tag should only be applied to other py_* targets.

Example:

load("@rules_venv//python:defs.bzl", "py_library")
load("@rules_venv//python/wheel:defs.bzl", "package_tag")

py_library(
    name = "my_target",
    tags = [package_tag("my_python_package")],
    # ...
    # ...
    # ...
)

PARAMETERS

NameDescriptionDefault Value
nameThe name of the packagenone

RETURNS

str: The tag.

py_wheel_library

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_library")

py_wheel_library(name, srcs, deps, data, abi, author, author_email, classifiers, constraints_file,
                 data_files, description_content_type, description_file, extra_distinfo_files,
                 homepage, license, platform, project_urls, python_requires, python_tag,
                 strip_path_prefixes, summary, version, distribution, repository_url, **kwargs)

Define a py_library with an associated wheel.

This rule will traverse dependencies (deps) to collect all data and dependencies that belong to the current package. Any dependency tagged with the package_tag whose name matches this targets name will be considered a submodule and included in the package.

Example:

load("@rules_venv//python:defs.bzl", "py_library")
load("@rules_venv//python/wheel:defs.bzl", "package_tag", "py_wheel_library")

py_library(
    name = "submodule",
    srcs = ["submodule.py"],
    tags = [
        # Note this name matches the name of the `py_wheel_library` target
        # and as a result will be included as a submodule within the wheel.
        package_tag("my_py_package")
    ],
)

py_wheel_library(
    name = "my_py_package",
    deps = [":submodule"],
)

Targets created by this library:

namedetails
{name}The py_library target for the wheel.
{name}.whlThe py_wheel target created from the {name} target.
{name}.publishA py_wheel_publisher target for publishing the wheel to a remote index. Defined only with repository_url.

PARAMETERS

NameDescriptionDefault Value
nameThe name of the target.none
srcsPython source files which make up the lirary.[]
depsA list of Python dependencies.[]
dataData required at runtime.[]
abiPython ABI tag. 'none' for pure-Python wheels.None
authorA string specifying the author of the package.None
author_emailA string specifying the email address of the package author.None
classifiersA list of strings describing the categories for the package. For valid classifiers see https://pypi.org/classifiersNone
constraints_fileA constraints (requirements.in) file which contains package constraints.None
data_files"Any file that is not normally installed inside site-packages goes into the .data directory, named as the .dist-info directory but with the .data/ extension. Allowed paths: ("purelib", "platlib", "headers", "scripts", "data")None
description_content_typeThe type of contents in description_file. If not provided, the type will be inferred from the extension of description_file. Also see https://packaging.python.org/en/latest/specifications/core-metadata/#description-content-typeNone
description_fileA file containing text describing the package.None
extra_distinfo_filesExtra files to add to distinfo directory in the archive.None
homepageA string specifying the URL for the package homepage.None
licenseA string specifying the license of the package.None
platformSupported platform. Use 'any' for pure-Python wheel.None
project_urlsA string dict specifying additional browsable URLs for the project and corresponding labels, where label is the key and url is the value. e.g {{"Bug Tracker": "http://bitbucket.org/tarek/distribute/issues/"}}None
python_requiresPython versions required by this distribution, e.g. '>=3.9,<3.13'None
python_tagSupported Python version(s), eg py3, cp39.cp310, etcNone
strip_path_prefixespath prefixes to strip from files added to the generated packageNone
summaryA one-line summary of what the distribution doesNone
versionThe version of the package."0.0.0"
distributionName of the distribution. If unset, name will be used.None
repository_urlThe repository (package index) URL to upload the wheel to.None
kwargsAdditional keyword arguments.none