-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add -t/--target
flag for uv pip install
#1517
Comments
I'd recommend not following pip's design here, as In particular, pip's choice of where to put binaries, scripts and include files is essentially arbitrary and may not be the best approach. |
I'd like to add that a key application of this is to enable the building of standalone zipapps that contain all of their dependencies. I have some workflows that use pip at the moment for this, and they would be massively accelerated if uv supported |
Added a thumbs up. I am also currently using -t from pip and would love to use uv for that use case instead! |
As mentioned by other people, Creating another solution from scratch is OK, but then |
That doesn't match with our experience on pip, where we have had a number of requests for better support for upgrades, etc. Another issue is pypa/pip#10110, which seems to revolve around people incrementally adding to a directory populated using But if
I don't think |
I also heavily use this feature to make stand alone envs. In my use case they are used to bootstrap workers in a cloud service. I too am only costumer of this use case Other past alternatives were conda pack and embedding in container which were both even slower than pip! Now desperately looking at this issue to see when I can reduce our 40 min env packing time when everything changes (there are various envs for various workers) to minutes or perhaps seconds :) For context, we already started using uv for our dev env |
We utilize pip's |
I second @matthew-chambers-pushly, @shayanhoshyari, et al. We do something similar to package for AWS Lambda. I think the general use case is:
Essentially what I want is something equivalent to this script: function uv.target(){
local target=${1?} ; shift
local args=("$@")
uv venv
# shellcheck source=/dev/null
source ".venv/bin/activate"
uv pip install "${args[@]}"
rm -rf "${target}" || true
mkdir -p "${target}/"
cp -r .venv/bin "${target}/"
cp -r .venv/lib/python3.*/site-packages/* "${target}/"
deactivate || true
rm -rf .venv
} |
FWIW, this matches our use case: The directory is empty. (Largely because of all the limitations described above regarding upgrade/uninstall.) |
This is the recipe for zip apps: $ mkdir tmp
$ pip install --no-compile --target=tmp . dep_1 dep_2
$ cd tmpdir
$ python -m zipapp --compress --python=/usr/bin/env python3 --main=myapp.__main__:main --output=../myapp.pyz Would be quite happy in this case to have the extra dirs (like bin) simply ignored, since they won't show up in the zipapp. |
without --prefix or --target it's really challenging to build multi stage images, my use case is copying packages to the final image. is there any workaround, waiting for any of these mechanisms to be supported? |
It depends how careful you want to be. If you don't mind being somewhat imprecise, the script from the comment above looks reasonable. It's Unix-specific and would need some tweaking for Windows because the If you want to handle wheels that have both |
Thanks for the extensive and fast answer! I'm basically trying to understand best practice for docker multi stage builds and uv, the script above won't quite do it as i cannot activate virtualenvs straight from dockerfiles. So far the only thing i managed to get working is:
is this the recommended way of doing it? are there any caveats I might stumble onto? i've tried multiple avenues but the lack of support for both |
I can't speak for
I'm not able to comment on your solution, as I don't really know what "i cannot activate virtualenvs straight from dockerfiles" means. |
i meant that i cannot source the activate script and that's why i do that ENV-setting. From your answer i understand that this should do it for now (which apparently isn't going to be long! 👍 ) |
You do not need to source the script. You can do |
I second |
thanks for the suggestions and compliments for the Dockerfile! I'll be waiting for |
Hi, I am bringing a thumbs up for a target or equivalent workflow here. In my company we store independently each package, because we have a different package resolver. I am loving UV and I hope a workflow to offer freedom could be present in the roadmap. |
I'm tempted to treat |
That’s more like pip’s With your proposal I would need to:
This is basically what pip does internally to implement |
@charliermarsh I would also like to share our use case and why your tempted approach might not be suitable for us. For AWS Lambda Functions you need to bundle dependencies locally or in CI. For example if you need the We mainly use the So its the last puzzle for us to get completely rid of pip. Big thanks to your effort, UV is already amazing and a productivity booster! |
@pfmoore - is there anywhere that I can read about the differences between |
Nothing much that I know of beyond the bare pip help information here. They both come from the original distutils install schemes, as far as I know. There's some discussion of the From my understanding, My view is that This is why I'd suggest that you start with a minimal approach that targets1 the known use cases, and extend it based on user feedback. So, for me, I'd go with:
To be honest, just implementing that shouldn't be too difficult. The hardest part would probably be integrating it into the code, as it's nothing like a "normal" install2. Footnotes
|
thanks, that sounds great! on 4 i'd recommend to still copy binaries. One example is "ddtrace", it does include a binary that one is supposed to call to wrap the python app to add telemetry - with my approach above that seems to work. |
Related to binaries, it looks like pip's |
Correct. But I don't know if that is right or helpful, which is why I suggest not doing so until there's feedback from real use cases that confirms it works and is needed. For example, I have no idea how Jupyter notebook could correctly find that path in a vendored situation - a brief search suggests that |
Thinking further about binaries, and in particular script wrappers, I don't even see how those can work in the general case. Assuming
So I'm unclear why there's any value in installing script wrappers, let alone worrying about where to save them. By the way, I'm aware that all of these points apply equally to pip - the main constraint with pip is that even if there's clearly no use for these things, if we remove them, there's bound to be someone whose workflow will break - https://xkcd.com/1172/. But as a new application, |
(By the way: I'm learning a lot from your comments and really appreciate you taking the time to provide input here. Thank you.) |
This has been a lovely thread filled with informative helpful people. Kudos to @pfmoore, @charliermarsh, and the rest of the |
@pfmoore - it could be okay though for scripts in (e.g.) (As opposed to (1) entrypoints and (2) scripts that hit the "Rewrite |
Yeah, those should work. In general, they are discouraged in favour of entry points, though (for various reasons that would be a digression here). The question, I guess, is whether you want to support this for what is in my experience a very small minority of packages, while also installing the other cases which in general won't work as the user expects. I'm trying to avoid over-complicating things here. You could include a "do you want to install scripts" option. Or even a "do you want to just install (possibly) safe scripts, or do you want to install everything" option. You could also offer options to install other sections of the wheel that aren't typically useful in a I'm not wedded to any particular option - even just "do what pip does" is an option. All I'm trying to do here is to explain that apart from the The only behaviours I strongly advise are:
And a third, I guess - keep it simple and be guided by actual use cases, rather than assuming "if pip has it, it must be important". (I'm also enjoying these discussions, by the way - it's nice to be able to take a fresh look at these sorts of design decisions, and actually think about what works best, rather than having to always think in terms of "what can we manage to do without breaking things" 🙂) |
## Summary The approach taken here is to model `--target` as an install scheme in which all the directories are just subdirectories of the `--target`. From there, everything else... just works? Like, upgrade, uninstalls, editables, etc. all "just work". Closes #1517.
This option is used a lot for vendoring and for custom build systems.
From
pip install --help
:The text was updated successfully, but these errors were encountered: