I'm trying to integrate poetry within my build and deploy process, and am having some difficulties with the latter.
So, build is working fine. I have code and a pyproject.toml file, and when I run poetry build -f wheel I get a wheel file, same as in my old build process. My next step would then consist of installing that wheel into a docker container, together with the dependent packages that I last tested it with. The dependency list would be the poetry.lock file, which I get for free, which is very nice. But I haven't seen a way to install my code as a wheel.
For illustration, this is what I imagine my dockerfile to look like:
FROM python:3.7-alpine
COPY pyproject.toml .
COPY poetry.lock .
COPY dist/* dist/ # only wheel, no code files
RUN pip install poetry && poetry install --no-dev --no-interaction
The resulting container will happily install all dependencies, but not the wheel I send along.
I could of course fix it by just adding pip install dist/*, but it felt wrong to call pip by hand after using poetry up to now.
How do I tell poetry to install the code I'm deploying as a wheel? If that's not possible, can I use pip to install the content of the poetry.lock file?
A few things I learned a little later
Just adding pip install dist/* doesn't solve the problem, since poetry installed the locked dependencies into a virtualenv, which I'd need to enter before running pip install. So, yeah. As expected, mixing deployment tools is no fun at all.
In case someone stumbled over this issue and wants to apply the hack:
RUN pip install poetry && \
poetry install --no-dev --no-interaction && \
source /root/.cache/pypoetry/virtualenvs/bookie-py3.7/bin/activate && \ # surely, this won't ever break
pip install dist/*
I finally managed to find some discussions on the matter, and their solutions look as clunky as mine. I guess at this point I am converging even more towards a solution where I try to get the lockfile into a state where pip can consume it, or just send a wheelhouse over instead.
The more I think about this whole thing, the more I feel like poetry isn't meant to be used by something that isn't a human. I guess the right approach to my pipeline problem is using poetry in the build stage, and exporting a wheelhouse instead of the lockfile from it. I'd be fine with closing this issue.
Instead of manually activating the virtual environment that Poetry makes, you can do poetry run pip install dist/*. But I wonder if that really does what you want/think, since poetry install --no-dev still installs your library, so if you try this, you'll get:
$ poetry run pip install dist/*.whl
Requirement already satisfied: foo==0.1.0 from file:///C:/tmp/foo/dist/foo-0.1.0 -py3-none-any.whl in c:\tmp\foo
...which won't actually install your wheel. For what you want, you'd probably need to do:
RUN pip install poetry && \
poetry install --no-dev --no-interaction && \
poetry run pip uninstall -y bookie && \
poetry run pip install dist/*
But that still feels kind of weird. This might not help if you have a specific reason for testing it the way you have in mind, but I think it would be more effective to split what you're doing into two tests:
Hey @mtkennerly , thanks for the help.
I'd probably go with this option:
Install with Poetry and exact pinned dependencies. This ignores the wheel and tests the known good setup.
But the problem here is that I can't find a way to isolate dependencies with poetry as something that isn't it's lockfile, so after I'm done building, I can't share my results with something that isn't poetry itself.
I either need a way to transform poetry's lockfile into something that pip can parse, or an equivalent to pip wheel -w put_wheels_here from poetry, which will not only build a wheel of my source code but also of all its dependencies, in a way where I can share it between different environments to reliably reproduce the build.
Gotcha. Sounds like you'd probably want the export command from 1.0.0a0 then.
See also: #558
Most helpful comment
Gotcha. Sounds like you'd probably want the
exportcommand from 1.0.0a0 then.