Skip to content

Commit

Permalink
Adds a pypi_file repo rule.
Browse files Browse the repository at this point in the history
Before we were guessing the URL at pythonhosted.org based on
pypi/warehouse#1944. This works in theory, but
there are over 100k wheels uploaded with the wrong python tags (i.e.,
the tag in index metadata doesn't match the tag in the .whl filename).

Instead, pypi_file takes a package name, version, filename, and sha256,
fetches package metadata from pypi (or a compatible index), and uses
that URL to download the package. It's still pure Bazel, thanks to the
PyPI JSON API and Bazel's JSON support.
  • Loading branch information
jvolkman committed May 3, 2022
1 parent 7131b4c commit 467ae94
Show file tree
Hide file tree
Showing 9 changed files with 710 additions and 556 deletions.
32 changes: 28 additions & 4 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ Public API re-exports

<pre>
pycross_lock_file(<a href="#pycross_lock_file-name">name</a>, <a href="#pycross_lock_file-always_build_packages">always_build_packages</a>, <a href="#pycross_lock_file-build_prefix">build_prefix</a>, <a href="#pycross_lock_file-build_target_overrides">build_target_overrides</a>,
<a href="#pycross_lock_file-default_alias_single_version">default_alias_single_version</a>, <a href="#pycross_lock_file-environment_prefix">environment_prefix</a>, <a href="#pycross_lock_file-file_url_overrides">file_url_overrides</a>, <a href="#pycross_lock_file-local_wheels">local_wheels</a>,
<a href="#pycross_lock_file-lock_model_file">lock_model_file</a>, <a href="#pycross_lock_file-out">out</a>, <a href="#pycross_lock_file-package_prefix">package_prefix</a>, <a href="#pycross_lock_file-remote_wheels">remote_wheels</a>, <a href="#pycross_lock_file-repo_prefix">repo_prefix</a>,
<a href="#pycross_lock_file-target_environments">target_environments</a>)
<a href="#pycross_lock_file-default_alias_single_version">default_alias_single_version</a>, <a href="#pycross_lock_file-environment_prefix">environment_prefix</a>, <a href="#pycross_lock_file-local_wheels">local_wheels</a>, <a href="#pycross_lock_file-lock_model_file">lock_model_file</a>,
<a href="#pycross_lock_file-out">out</a>, <a href="#pycross_lock_file-package_prefix">package_prefix</a>, <a href="#pycross_lock_file-pypi_index">pypi_index</a>, <a href="#pycross_lock_file-remote_wheels">remote_wheels</a>, <a href="#pycross_lock_file-repo_prefix">repo_prefix</a>, <a href="#pycross_lock_file-target_environments">target_environments</a>)
</pre>


Expand All @@ -26,11 +25,11 @@ pycross_lock_file(<a href="#pycross_lock_file-name">name</a>, <a href="#pycross_
| <a id="pycross_lock_file-build_target_overrides"></a>build_target_overrides | A mapping of package keys (name-version) to existing pycross_wheel_build build targets. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="pycross_lock_file-default_alias_single_version"></a>default_alias_single_version | Generate aliases for all packages that have a single version in the lock file. | Boolean | optional | False |
| <a id="pycross_lock_file-environment_prefix"></a>environment_prefix | An optional prefix to apply to environment targets. Defaults to _env | String | optional | "_env" |
| <a id="pycross_lock_file-file_url_overrides"></a>file_url_overrides | An optional mapping of wheel or sdist filenames to their URLs. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="pycross_lock_file-local_wheels"></a>local_wheels | A list of wheel files. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="pycross_lock_file-lock_model_file"></a>lock_model_file | The lock model JSON file. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
| <a id="pycross_lock_file-out"></a>out | The output file. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
| <a id="pycross_lock_file-package_prefix"></a>package_prefix | An optional prefix to apply to package targets. | String | optional | "" |
| <a id="pycross_lock_file-pypi_index"></a>pypi_index | The PyPI-compatible index to use (must support the JSON API). | String | optional | "" |
| <a id="pycross_lock_file-remote_wheels"></a>remote_wheels | A mapping of remote wheels to their sha256 hashes. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="pycross_lock_file-repo_prefix"></a>repo_prefix | The prefix to apply to repository targets. Defaults to the lock file target name. | String | optional | "" |
| <a id="pycross_lock_file-target_environments"></a>target_environments | A list of pycross_target_environment labels. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
Expand Down Expand Up @@ -143,3 +142,28 @@ pycross_wheel_library(<a href="#pycross_wheel_library-name">name</a>, <a href="#
| <a id="pycross_wheel_library-wheel"></a>wheel | The wheel file. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |


<a id="#pypi_file"></a>

## pypi_file

<pre>
pypi_file(<a href="#pypi_file-name">name</a>, <a href="#pypi_file-filename">filename</a>, <a href="#pypi_file-index">index</a>, <a href="#pypi_file-keep_metadata">keep_metadata</a>, <a href="#pypi_file-package_name">package_name</a>, <a href="#pypi_file-package_version">package_version</a>, <a href="#pypi_file-repo_mapping">repo_mapping</a>, <a href="#pypi_file-sha256">sha256</a>)
</pre>

Downloads a file from a PyPI-compatible package index.

**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="pypi_file-name"></a>name | A unique name for this repository. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="pypi_file-filename"></a>filename | The name of the file to download. | String | required | |
| <a id="pypi_file-index"></a>index | The base URL of the PyPI-compatible package index to use. Defaults to pypi.org. | String | optional | "https://pypi.org" |
| <a id="pypi_file-keep_metadata"></a>keep_metadata | Whether to store the pypi_metadata.json file for debugging. | Boolean | optional | False |
| <a id="pypi_file-package_name"></a>package_name | The package name. | String | required | |
| <a id="pypi_file-package_version"></a>package_version | The package version. | String | required | |
| <a id="pypi_file-repo_mapping"></a>repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.&lt;p&gt;For example, an entry <code>"@foo": "@bar"</code> declares that, for any time this repository depends on <code>@foo</code> (such as a dependency on <code>@foo//some:target</code>, it should actually resolve that dependency within globally-declared <code>@bar</code> (<code>@bar//some:target</code>). | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | required | |
| <a id="pypi_file-sha256"></a>sha256 | The expected SHA-256 of the file downloaded. | String | required | |


5 changes: 3 additions & 2 deletions example/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ pycross_lock_file(
":python_darwin_arm64",
":python_linux_x86_64",
],
file_url_overrides = {
"xmltodict-0.12.0-py2.py3-none-any.whl": "https://files.pythonhosted.org/packages/3.7/x/xmltodict/xmltodict-0.12.0-py2.py3-none-any.whl",
remote_wheels = {
"https://files.pythonhosted.org/packages/3.7/x/xmltodict/xmltodict-0.12.0-py2.py3-none-any.whl": "8bbcb45cc982f48b2ca8fe7e7827c5d792f217ecf1792626f808bf41c3b86051",
},
local_wheels = [
"//wheels",
Expand All @@ -90,6 +90,7 @@ pycross_lock_file(
always_build_packages = [
"pbr-5.8.1",
],
pypi_index = "https://pypi.org",
out = "example_lock.bzl",
)

Expand Down
Loading

0 comments on commit 467ae94

Please sign in to comment.