:::{default-domain} bzl :::
:::{note}
Currently rules_python only supports requirements.txt format.
#{gh-issue}2787 tracks pylock.toml support.
:::
When working on a Python project, you will have dependencies that themselves
have transitive dependencies. You can generate a full list of transitive
dependencies and pinned versions in requirements_lock.txt using the
{obj}lock rule with uv:
load("@rules_python//python/uv:lock.bzl", "lock")
lock(
name = "requirements",
srcs = ["pyproject.toml", "requirements.in"],
out = "requirements_lock.txt",
)When a pyproject.toml file is among the {attr}lock.srcs, the
{obj}lock rule auto-detects the project directory and passes
--project <dir> to uv pip compile. This causes uv to read
[tool.uv] settings from that pyproject.toml, such as
no-build-isolation, exclude-dependencies, and workspace members.
If multiple pyproject.toml files are in {attr}lock.srcs, the one
with the shortest directory path is selected (this heuristic works for
typical uv workspace layouts where the root configuration is at the
shortest path).
If the auto-detection picks the wrong project directory, use the
project parameter to override:
lock(
name = "requirements",
srcs = ["pyproject.toml", "requirements.in"],
out = "requirements_lock.txt",
project = "subproject",
):::{warning} Known limitations of auto-detection
- Workspace heuristic — the shortest-path selection may incorrectly assume the upper-most
workspace
pyproject.tomlis the correct one. For monorepos with multiple independent sub-projects, you must setprojectexplicitly for each {obj}locktarget. - No test target — unlike {obj}
compile_pip_requirements, no test target is auto-created; see the {obj}lockdocs for how to add one manually usingdiff_testfrombazel_skylib. :::
For WORKSPACE projects or when using pip-compile, you can manage pinned
dependencies with {obj}compile_pip_requirements:
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
compile_pip_requirements(
name = "requirements",
src = "pyproject.toml",
requirements_txt = "requirements_lock.txt",
)This rule generates two targets:
bazel run [name].updatewill regenerate therequirements_txtfilebazel test [name]_testwill test that therequirements_txtfile is up to date
Once you generate this fully specified list of requirements, you can install the requirements (bzlmod/WORKSPACE).
:::{warning}
If you're specifying dependencies in pyproject.toml, make sure to include the
[build-system] configuration, with pinned dependencies.
compile_pip_requirements will use the build system specified to read your
project's metadata, and you might see non-hermetic behavior if you don't pin the
build system.
Not specifying [build-system] at all will result in using a default
[build-system] configuration, which uses unpinned versions
(ref).
:::
pip-compile doesn't yet support pyproject.toml dependency groups. Follow pip-tools #2062 to see the status of their support.
In the meantime, support can be emulated by passing multiple files to srcs:
compile_pip_requirements(
srcs = ["pyproject.toml", "requirements-dev.in"]
...
)For more documentation see {obj}lock.