Skip to content

Commit 89bed46

Browse files
committed
document the pypi.install
1 parent 93f8d4c commit 89bed46

File tree

1 file changed

+84
-53
lines changed

1 file changed

+84
-53
lines changed

docs/pypi-dependencies.md

Lines changed: 84 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ Using PyPI packages (aka "pip install") involves two main steps.
1313

1414
### Using bzlmod
1515

16-
To add pip dependencies to your `MODULE.bazel` file, use the `pip.parse`
17-
extension, and call it to create the central external repo and individual wheel
18-
external repos. Include in the `MODULE.bazel` the toolchain extension as shown
19-
in the first bzlmod example above.
16+
To add pip dependencies to your `MODULE.bazel` file, use the {bzl:obj}`pip.parse` or
17+
{bzl:obj}`pypi.install` extension, and call it to create the central external
18+
repo and individual wheel external repos. Include in the `MODULE.bazel` the
19+
toolchain extension as shown in the first bzlmod example above.
2020

2121
```starlark
2222
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
@@ -27,6 +27,7 @@ pip.parse(
2727
)
2828
use_repo(pip, "my_deps")
2929
```
30+
3031
For more documentation, including how the rules can update/create a requirements
3132
file, see the bzlmod examples under the {gh-path}`examples` folder or the documentation
3233
for the {obj}`@rules_python//python/extensions:pip.bzl` extension.
@@ -44,6 +45,78 @@ hermetic host python interpreter on this platform. Linux and OSX users should se
4445
difference.
4546
```
4647

48+
(bazel-downloader)=
49+
#### Using `pypi.install` extension
50+
51+
:::{warning}
52+
The APIs here have been well tested but may still change in backwards
53+
incompatible ways if major design flaws are found.
54+
:::
55+
56+
`pypi.install` provides almost a drop-in replacement for the `pip.parse` extension:
57+
```starlark
58+
pypi = use_extension("@rules_python//python/extensions:pypi.bzl", "pypi")
59+
pypi.install(
60+
hub_name = "my_deps",
61+
python_version = "3.11",
62+
requirements_lock = "//:requirements_lock_3_11.txt",
63+
)
64+
use_repo(pypi, "my_deps")
65+
```
66+
67+
The `bzlmod` `pypi.install` call supports pulling information from `PyPI` (or a
68+
compatible mirror) and it will ensure that the [bazel
69+
downloader][bazel_downloader] is used for downloading the wheels or the sdists
70+
in the requirements file. This allows the users to use the [credential
71+
helper](#credential-helper) to authenticate with the mirror and it also ensures
72+
that the distribution downloads are cached.
73+
It also avoids using `pip` altogether and results in much faster dependency
74+
fetching.
75+
76+
See the {gh-path}`examples/bzlmod/MODULE.bazel` example for more info.
77+
78+
:::{warning}
79+
For now there is a limitation that the lock
80+
files consumed by the `pypi.install` extension must have hashes, similarly to
81+
all our examples. Hence, the `requirements.txt` files produced by `pip lock` or
82+
by `uv pip compile` but without generating hashes will fail.
83+
:::
84+
85+
Note, when using this feature during the `pip` extension evaluation you will see the accessed indexes similar to below:
86+
```console
87+
Loading: 0 packages loaded
88+
currently loading: docs/
89+
Fetching module extension pip in @@//python/extensions:pypi.bzl; starting
90+
Fetching https://pypi.org/simple/twine/
91+
```
92+
93+
This does not mean that `rules_python` is fetching the wheels eagerly, but it
94+
rather means that it is calling the PyPI server to get the Simple API response
95+
to get the list of all available source and wheel distributions. Once it has
96+
got all of the available distributions, it will select the right ones depending
97+
on the `sha256` values in your `requirements_lock.txt` file. The compatible
98+
distribution URLs will be then written to the `MODULE.bazel.lock` file. Currently
99+
users wishing to use the lock file with `rules_python` with this feature have
100+
to set an environment variable `RULES_PYTHON_OS_ARCH_LOCK_FILE=0` which will
101+
become default in the next release.
102+
103+
Fetching the distribution information from the PyPI allows `rules_python` to
104+
know which `whl` should be used on which target platform and it will determine
105+
that by parsing the `whl` filename based on [PEP600], [PEP656] standards. This
106+
allows the user to configure the behaviour by using the following publicly
107+
available flags:
108+
* {obj}`--@rules_python//python/config_settings:py_linux_libc` for selecting the Linux libc variant.
109+
* {obj}`--@rules_python//python/config_settings:pip_whl` for selecting `whl` distribution preference.
110+
* {obj}`--@rules_python//python/config_settings:pip_whl_osx_arch` for selecting MacOS wheel preference.
111+
* {obj}`--@rules_python//python/config_settings:pip_whl_glibc_version` for selecting the GLIBC version compatibility.
112+
* {obj}`--@rules_python//python/config_settings:pip_whl_muslc_version` for selecting the musl version compatibility.
113+
* {obj}`--@rules_python//python/config_settings:pip_whl_osx_version` for selecting MacOS version compatibility.
114+
115+
[bazel_downloader]: https://bazel.build/rules/lib/builtins/repository_ctx#download
116+
[pep600]: https://peps.python.org/pep-0600/
117+
[pep656]: https://peps.python.org/pep-0656/
118+
119+
47120
### Using a WORKSPACE file
48121

49122
To add pip dependencies to your `WORKSPACE`, load the `pip_parse` function and
@@ -134,6 +207,13 @@ re-executed to pick up a non-hermetic change to your environment (e.g., updating
134207
your system `python` interpreter), you can force it to re-execute by running
135208
`bazel sync --only [pip_parse name]`.
136209

210+
:::{note}
211+
The same is not necessarily true for the `pypi.install` bazel extension as it is
212+
not relying on the built in interpreter environment information and yields the same
213+
set of dependencies irrespective of the host machine and the python interpreter used
214+
to pull the Python dependencies.
215+
:::
216+
137217
{#using-third-party-packages}
138218
## Using third party packages as dependencies
139219

@@ -306,55 +386,6 @@ leg of the dependency manually. For instance by making
306386
`apache-airflow-providers-postgres` not explicitly depend on `apache-airflow` or
307387
perhaps `apache-airflow-providers-common-sql`.
308388

309-
310-
(bazel-downloader)=
311-
### Bazel downloader and multi-platform wheel hub repository.
312-
313-
The `bzlmod` `pip.parse` call supports pulling information from `PyPI` (or a
314-
compatible mirror) and it will ensure that the [bazel
315-
downloader][bazel_downloader] is used for downloading the wheels. This allows
316-
the users to use the [credential helper](#credential-helper) to authenticate
317-
with the mirror and it also ensures that the distribution downloads are cached.
318-
It also avoids using `pip` altogether and results in much faster dependency
319-
fetching.
320-
321-
This can be enabled by `experimental_index_url` and related flags as shown in
322-
the {gh-path}`examples/bzlmod/MODULE.bazel` example.
323-
324-
When using this feature during the `pip` extension evaluation you will see the accessed indexes similar to below:
325-
```console
326-
Loading: 0 packages loaded
327-
currently loading: docs/
328-
Fetching module extension pip in @@//python/extensions:pip.bzl; starting
329-
Fetching https://pypi.org/simple/twine/
330-
```
331-
332-
This does not mean that `rules_python` is fetching the wheels eagerly, but it
333-
rather means that it is calling the PyPI server to get the Simple API response
334-
to get the list of all available source and wheel distributions. Once it has
335-
got all of the available distributions, it will select the right ones depending
336-
on the `sha256` values in your `requirements_lock.txt` file. The compatible
337-
distribution URLs will be then written to the `MODULE.bazel.lock` file. Currently
338-
users wishing to use the lock file with `rules_python` with this feature have
339-
to set an environment variable `RULES_PYTHON_OS_ARCH_LOCK_FILE=0` which will
340-
become default in the next release.
341-
342-
Fetching the distribution information from the PyPI allows `rules_python` to
343-
know which `whl` should be used on which target platform and it will determine
344-
that by parsing the `whl` filename based on [PEP600], [PEP656] standards. This
345-
allows the user to configure the behaviour by using the following publicly
346-
available flags:
347-
* {obj}`--@rules_python//python/config_settings:py_linux_libc` for selecting the Linux libc variant.
348-
* {obj}`--@rules_python//python/config_settings:pip_whl` for selecting `whl` distribution preference.
349-
* {obj}`--@rules_python//python/config_settings:pip_whl_osx_arch` for selecting MacOS wheel preference.
350-
* {obj}`--@rules_python//python/config_settings:pip_whl_glibc_version` for selecting the GLIBC version compatibility.
351-
* {obj}`--@rules_python//python/config_settings:pip_whl_muslc_version` for selecting the musl version compatibility.
352-
* {obj}`--@rules_python//python/config_settings:pip_whl_osx_version` for selecting MacOS version compatibility.
353-
354-
[bazel_downloader]: https://bazel.build/rules/lib/builtins/repository_ctx#download
355-
[pep600]: https://peps.python.org/pep-0600/
356-
[pep656]: https://peps.python.org/pep-0656/
357-
358389
(credential-helper)=
359390
### Credential Helper
360391

0 commit comments

Comments
 (0)