Open helderco opened 8 months ago
My use case for this is building a docker image, but I'm not using Rye there (only in dev). Just using uv directly in the container:
# copy only requirements.lock uv install --no-deps -r requirements.lock # copy all files uv install --no-deps -e .
Have you tried to use a simple linux image with minimal dependencies (like a slim one) and rely on rye + uv to install the python and the dependencies? If you defined a rye script to launch your app this looks like an amazing fast way to build a docker no?
Not to hijack this Issue as I think the possibility to do what you highlighted would be beneficial, but I'm also looking for the best/easiest/fastest way to build a Docker app with rye
🤗
I'm planning on trying that, but only in a specific case. The use case I mention above affects all users of a platform, so I need something more production-ready.
But I'm very interested in the fastest way to build a container that is able to run a python app. In this case speed is more important than disk space.
I think it might make sense to remove the packages themselves from the lock file. I'm not opposed to it, but I did not spend so much time thinking about the implications of that yet.
Okay, after playing around with building docker images for a bit, here's my humble opinion on this:
This is basically a trade-off: If you want all the dependencies and the project itself to be installed, the -e file:.
in the lockfile is useful, since you can install it all in a single command. But if you don't want to install the project itself, you'll need to do weird sed
hacks to do that.
Not having -e file:.
in the lockfile means that you'll need a second command to install the package itself if you want it, which is a minor inconvenience. But you don't need any weird hacks to just install the dependencies, which is pretty nice.
During development, this doesn't matter, since people are going to use rye
itself anyway. But when deploying, there are situations where you want to install the dependencies only. This is obviously the case when using docker to get better layer caching. But it also has advantages when installing the project on bare metal, since it allows you to do this:
pip install --no-deps -r requirements.lock
pip install --no-deps dist/my-project-name.whl # (needs to be pre-built obv.)
This avoids any (slow) dependency resolution and ensures that the dependencies are exactly the same as those that were locked. It also avoids having to install build dependencies on a production machine.
So yeah, I think it's a much more common case that people want to install dependencies only. But even if that's not the case, the inconvenience of typing pip install -e .
if you want it is also much lower than typing sed -i '/^-e /d' *.lock
if you don't.
I just had to go through quite complex hoops in order to overcome the existing behavior. I want to use the requirements.lock
file generated by rye as an input to Bazel's pip_parse
in rules_python
. It didn't work because of the -e file:.
line, and I had to write a special "repository rule" in order to remove it.
So, just another reason for removing this from requirements.lock
. I think that the lock file should only contain the dependencies, not extra lines which makes some uses of it more convenient and other uses much less convenient.
I'm planning on trying that, but only in a specific case. The use case I mention above affects all users of a platform, so I need something more production-ready.
Just an update on this. I did try using a small image, install rye and get Python through that but it took twice as long as getting the official slim Python. Adding rye to that slim adds overhead but uv via oci image is worth it.
I can add a use case:
I want to use pip-audit (https://github.com/pypa/pip-audit) to check my dependencies using requirements.lock
pip-audit --disable-pip --requirement requirements.lock
does not work due to the line -e file: .
Another use case:
I want to utilise docker cache, to speed up CI pipeline
# install only deps
COPY pyproject.toml requirements.lock /app/
RUN rye sync --no-dev --no-lock --virtual
# install project
COPY src/ /app/src
RUN rye sync --no-dev --no-lock
An other reason is that this -e file: .
prevents installing dependencies using pip install --no-cache-dir -r requirements.lock
in a Dockerfile
if you used https://rye.astral.sh/guide/pyproject/#toolryegenerate-hashes !
In that case, you will get this error:
Obtaining file:///. (from -r requirements.lock (line 12)) ERROR: The editable requirement file:///. (from -r requirements.lock (line 12)) cannot be installed when requiring hashes, because there is no single file to hash.
I suggested this in https://github.com/astral-sh/rye/discussions/239#discussioncomment-8802791, so I'm aware of:
Rather than needing the
sed
workaround to remove-e file:.
from the lock file, I'd much prefer having the lock represent dependencies only and having Rye implicitly installing the current project in editable mode (for non-virtual projects).Then have an option, similar to Poetry's --no-root, to not install the current project with the dependencies.
This way, the current workflow continues to work, workspaces still added as
-e
to the lock and that's fine, and there's an escape hatch for those that want to install dependencies seperately from the current project.My use case for this is building a docker image, but I'm not using Rye there (only in dev). Just using uv directly in the container: