I have a Python project with Poetry which i would like to upload to CodeArtifact (like any other Python Repository) and then install it into a Docker container. My Python project has dependencies in the pyproject.toml like
[tool.poetry.dependencies]
pandas = "^2.1.4"
pytest-mock = "^3.12.0"
the ^ means that even higher versions are accepted. But as soon as I have my project working I also have a poetry.lock file. This prevents higher versions from being installed with poetry install.
Now when everything is working, I run poetry build and upload the lib to CodeArtifact.
If I want to install this library into a Docker container, I could run pip install and specify the version of my lib.
My questions are now:
- Is this installation going to respect the
poetry.lockfile? Or is it going to install the latest dependencies for examplepandas 2.2.0 - How can I prevent newer versions? Which is to say: Do I have to remove it from the pyproject.toml file? Or do have to copy the lock file to the container and run
poetry install?
If you've run
poetry buildto create a package and uploaded that package to codeartifact, that package is now ready to be installed by a package manager (egpip installorpoetry add), regardless of whether the "caller" is in a container.Making your container dependencies mirror your local project
If you want to make your dependency versions follow the
poetry.lockand exactly mirror those in your local project, you can install Poetry in your container, copy in thepoetry.lockfrom your local project, and do poetry install in the container.Here's an example (several, actually) of how this is done.
How dependency resolution works
Dependency management tools like Pip and Poetry will look at the dependencies specified in the
pyproject.tomlof each of the dependencies in your project, compare them with each other, and determine which dependency versions will satisfy the project (and dependency requirements) without causing conflicts.In your case, this means that the version of Pandas that gets installed will change based on your environment and the other dependencies in the project.
A concrete example:
poetry build, making Foo an installable packagepyproject.toml, that specifies its dependency requirementspip install fooThe behavior is as follows:
These dependency managers are "smart" in that they will upgrade dependencies only as high as the dependencies will support.
For example:
barthat relies onmydep = <=2.0.5quxthat relies onmydep = <=2.1.0How to prevent higher versions
IMPORTANT: Pip and Poetry respect semantic versioning. Semantic versioning highlights breaking changes to libraries (changes in public API, etc), so dependency managers know "just how far they can upgrade" without breaking your code. It is not recommended to manually edit versions requirements - this is what dependency managers like Poetry are for!
Now with that caveat, you can use "less than or equals" notation in your requirements files (typically
pyproject.toml) to "lock" a dependency at a particular version or set a cap. Eg.mydep = <=2.0.5will go no higher than 2.0.5 andmydep = =2.0.5will be exactly 2.0.5. Then if you have poetry for example, you'd runpoetry update mydepto lock that change into yourpoetry.lockfile.