Skip to content

Build hook plugins


A build hook provides code that will be executed at various stages of the build process. See the documentation for build hook configuration.

Known third-party

Overview

Build hooks run for every selected version of build targets.

The initialization stage occurs immediately before each build and the finalization stage occurs immediately after. Each stage has the opportunity to view or modify build data.

Build data

Build data is a simple mapping whose contents can influence the behavior of builds. Which fields exist and are recognized depends on each build target.

The following fields are always present and recognized by the build system itself:

Field Type Description
artifacts list[str] This is a list of extra artifact patterns and should generally only be appended to
force_include dict[str, str] This is a mapping of extra forced inclusion paths, with this mapping taking precedence in case of conflicts
build_hooks tuple[str, ...] This is an immutable sequence of the names of the configured build hooks and matches the order in which they run

Attention

While user-facing TOML options are hyphenated, build data fields should be named with underscores to allow plugins to use them as valid Python identifiers.

Notes

In some cases it may be necessary to use force_include rather than artifacts. For example, say that you want to install a lib.so directly at the root of site-packages and a project defines a package src/foo. If you create src/lib.so, there will never be a match because the directory traversal starts at src/foo rather than src. In that case you must do either:

build_data['force_include']['src/lib.so'] = 'src/lib.so'

or

build_data['force_include']['/absolute/path/to/src/lib.so'] = 'src/lib.so'

BuildHookInterface

Example usage:

from hatchling.builders.hooks.plugin.interface import BuildHookInterface


class SpecialBuildHook(BuildHookInterface):
    PLUGIN_NAME = 'special'
    ...
from hatchling.plugin import hookimpl

from .plugin import SpecialBuildHook


@hookimpl
def hatch_register_build_hook():
    return SpecialBuildHook
Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
class BuildHookInterface(Generic[BuilderConfigBound]):  # no cov
    """
    Example usage:

    ```python tab="plugin.py"
    from hatchling.builders.hooks.plugin.interface import BuildHookInterface


    class SpecialBuildHook(BuildHookInterface):
        PLUGIN_NAME = 'special'
        ...
    ```

    ```python tab="hooks.py"
    from hatchling.plugin import hookimpl

    from .plugin import SpecialBuildHook


    @hookimpl
    def hatch_register_build_hook():
        return SpecialBuildHook
    ```
    """

    PLUGIN_NAME = ''
    """The name used for selection."""

    def __init__(
        self,
        root: str,
        config: dict[str, Any],
        build_config: BuilderConfigBound,
        metadata: ProjectMetadata,
        directory: str,
        target_name: str,
        app: Application | None = None,
    ) -> None:
        self.__root = root
        self.__config = config
        self.__build_config = build_config
        self.__metadata = metadata
        self.__directory = directory
        self.__target_name = target_name
        self.__app = app

    @property
    def app(self) -> Application:
        """
        An instance of [Application](../utilities.md#hatchling.bridge.app.Application).
        """
        if self.__app is None:
            from hatchling.bridge.app import Application

            self.__app = cast(Application, Application().get_safe_application())

        return self.__app

    @property
    def root(self) -> str:
        """
        The root of the project tree.
        """
        return self.__root

    @property
    def config(self) -> dict[str, Any]:
        """
        The cumulative hook configuration.

        ```toml config-example
        [tool.hatch.build.hooks.<PLUGIN_NAME>]
        [tool.hatch.build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]
        ```
        """
        return self.__config

    @property
    def metadata(self) -> ProjectMetadata:
        # Undocumented for now
        return self.__metadata

    @property
    def build_config(self) -> BuilderConfigBound:
        """
        An instance of [BuilderConfig](../utilities.md#hatchling.builders.config.BuilderConfig).
        """
        return self.__build_config

    @property
    def directory(self) -> str:
        """
        The build directory.
        """
        return self.__directory

    @property
    def target_name(self) -> str:
        """
        The plugin name of the build target.
        """
        return self.__target_name

    def clean(self, versions: list[str]) -> None:
        """
        This occurs before the build process if the `-c`/`--clean` flag was passed to
        the [`build`](../../cli/reference.md#hatch-build) command, or when invoking
        the [`clean`](../../cli/reference.md#hatch-clean) command.
        """

    def initialize(self, version: str, build_data: dict[str, Any]) -> None:
        """
        This occurs immediately before each build.

        Any modifications to the build data will be seen by the build target.
        """

    def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
        """
        This occurs immediately after each build and will not run if the `--hooks-only` flag
        was passed to the [`build`](../../cli/reference.md#hatch-build) command.

        The build data will reflect any modifications done by the target during the build.
        """

PLUGIN_NAME = '' class-attribute instance-attribute

The name used for selection.

app: Application property

An instance of Application.

root: str property

The root of the project tree.

config: dict[str, Any] property

The cumulative hook configuration.

[tool.hatch.build.hooks.<PLUGIN_NAME>]
[tool.hatch.build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]
[build.hooks.<PLUGIN_NAME>]
[build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]

build_config: BuilderConfigBound property

An instance of BuilderConfig.

target_name: str property

The plugin name of the build target.

directory: str property

The build directory.

clean(versions: list[str]) -> None

This occurs before the build process if the -c/--clean flag was passed to the build command, or when invoking the clean command.

Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def clean(self, versions: list[str]) -> None:
    """
    This occurs before the build process if the `-c`/`--clean` flag was passed to
    the [`build`](../../cli/reference.md#hatch-build) command, or when invoking
    the [`clean`](../../cli/reference.md#hatch-clean) command.
    """

initialize(version: str, build_data: dict[str, Any]) -> None

This occurs immediately before each build.

Any modifications to the build data will be seen by the build target.

Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
    """
    This occurs immediately before each build.

    Any modifications to the build data will be seen by the build target.
    """

finalize(version: str, build_data: dict[str, Any], artifact_path: str) -> None

This occurs immediately after each build and will not run if the --hooks-only flag was passed to the build command.

The build data will reflect any modifications done by the target during the build.

Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
    """
    This occurs immediately after each build and will not run if the `--hooks-only` flag
    was passed to the [`build`](../../cli/reference.md#hatch-build) command.

    The build data will reflect any modifications done by the target during the build.
    """