Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incrementally download wheels at workspace time. #432

Merged
merged 14 commits into from
Mar 22, 2021

Conversation

hrfuller
Copy link
Contributor

@hrfuller hrfuller commented Mar 8, 2021

Commits in this PR can be reviewed individually, they build on each other.

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature (please, look at the "Scope of the project" section in the README.md file)
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

The current pip_install repository rule requires that all pip packages be resolved and downloaded before bazel can start to run build actions. This can lead to painful wait times when invoking pip_install with large requirement.txt files on clean repos, or whenever changes to the external repo configurations are made.

Issue Number: #395

What is the new behavior?

Add an experimental repository rule called pip_install_incremental. Which sets up an external repository for each package in the requirements lock file passed by users.

The largest difference from pip_install is that pip_install_incremental doesn't do a full resolve over the requirements_lock file passed in. As such users must supply a requirements_lock.txt file containing fully resolved and pinned transitive closure of the pypi dependencies needed by their workspace. We don't provide a way to resolve a requirements lock file in this PR, nor do we verify the integrity of the lock file, but we could provide something in the future to do this.

Does this PR introduce a breaking change?

  • Yes
  • No

@google-cla google-cla bot added the cla: yes label Mar 8, 2021
@hrfuller hrfuller requested review from lberki and removed request for andyscott, brandjon and lberki March 8, 2021 04:36
hrfuller added 6 commits March 7, 2021 21:00
Refactor pip_repository rule to invoke different scripts based on the
value of the incremental attribute to the rule.
Create a new macro in repositories.bzl which in the context of an
incremental repo will instantiate all the child repos representing
individual python packages.
Refactor code which is repeated between the create_incremental_repo
scripts and the extract wheels script.
@hrfuller hrfuller force-pushed the hrfuller/incremental_deps_import branch from 9d804e7 to 4e1c72f Compare March 8, 2021 05:02
python/pip.bzl Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
@hrfuller
Copy link
Contributor Author

hrfuller commented Mar 15, 2021 via email

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
examples/pip_install_incremental/WORKSPACE Outdated Show resolved Hide resolved
examples/pip_install_incremental/requirements_lock.txt Outdated Show resolved Hide resolved
README.md Outdated
load("@rules_python//python:pip.bzl", "pip_install_incremental")

# Create a central repo that knows about the dependencies needed for
# requirements.txt.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there ever a use-case like in rules_go where I'd want to check in that resulting requirements.bzl file so I could hand-edit? like to patch maybe?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an interesting idea. I think they'd probably be platform dependent potentially.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, but to me that would suggest that the resolver you used didn't do a good job applying your requirements / constraints. Let's revisit that if it comes up?

python/pip_install/create_incremental_repo/BUILD Outdated Show resolved Hide resolved
args.requirements_lock = requirements_lock.name
args.repo = "pip_incremental"
contents = generate_incremental_requirements_contents(args)
library_target = sanitised_repo_library_label("foo", create_incremental_repo_prefix(args.repo))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in a test I'd prefer you hardcode expected values rather than calculate them, both to document what it looks like, and as an additional assertion that the sanitised_* helper does what we expect

python/pip_install/extract_wheels/lib/utilities.py Outdated Show resolved Hide resolved
- Rename helpers and executables to match this new convention.
- Make readme more readable.
- Add integration test for the example.
Use a requirements_lock.txt which is compatible with the cp3.5 platform.
@hrfuller
Copy link
Contributor Author

Hey @alexeagle would you take another look when you get a change. I believe I addressed all concerns.

repo_name = "foo"
index_url = "--index_url=pypi.org/simple"
args_dict = vars(parser.parse_args(
args=["--repo", repo_name, "--extra_pip_args={index_url}".format(index_url=index_url)]))
Copy link

@skliarpawlo skliarpawlo Mar 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thanks for the feature, we are already trying to use it from the PR directly and it's a game-changer!

Problem: we use our own PyPi index in requirements.txt (--index-url=... at the top of the requirements file) and it seems like it is being ignored (I can be wrong or misusing the tool), but if that is the case, it would be great if that is passed to extra_pip_args automatically.

Also when we try to pass the pypi url via pip_extra_args explicitly, like this:

pip_parse(
    name = "my_repo",
    quiet = False,
    timeout = 1500,
    requirements_lock = "@//.../requirements-lock.txt",
    python_interpreter = "python3.7",
    extra_pip_args=["--index-url=http://<pypi-host>/repository/pypi-all/simple", "--trusted-host=<pypi-host>"]
)

We get an error, like this:

ERROR: .../WORKSPACE:50:13: //external:repo_pypi__setuptools: expected value of type 'list(string)' for attribute 'extra_pip_args' in 'whl_library' rule, but got "{\"args\":[\"--index-url=http://.../repository/pypi-all/simple\"]}" (string)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey thanks for the feedback, I probably missed the --index-url argument. I'll try to repro the issue with extra_pip_args as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed the issue with --extra_pip_args not being passed to the child repos correctly. I will leave the issue of pip flags in a requirements.txt file as a TODO, as this is an experimental rule for the moment.

Don't write serialized json into the generated requirements.bzl file
because whl_library doesn't understand it.
Copy link
Contributor

@alexeagle alexeagle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!!

@hrfuller hrfuller merged commit 7aaf762 into master Mar 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants