On some occasions, I saw myself needing to prepare wheelhouses, for distribution on environments that have neither internet nor any PyPI-compatible index access. As per pip’s documentation, a wheelhouse can be built using either pip wheel
or pip download
. Generally, I do these steps separately, because it’s easier to distribute, use and distinguish what is the package itself from what is the dependency of said package. As most of my packages are Pure-python, I’m worried mostly with the dependencies themselves (transitive or otherwise).
If you issue a pip download
with no platform tags, pip
uses the current environment’s platform to determine which built distributions to download. It appears it gives preference to them, and if not found, a source distribution will be downloaded instead. Then, all you need to do is do a pip install
with the list of all distributions. As per the documentation, follows an example:
PROJECT_ROOT="$(pwd)"
cd "${PROJECT_ROOT}"
mkdir -p dist/wheelhouse
pip3 download -d dist/wheelhouse .
Then, to install:
# Just an example. Could be done some other way as well (e.g. user/global install)
VENV_DIR="$(pwd)/venv"
python3 -m venv "${VENV_DIR}"
cd "${PROJECT_ROOT}/dist/wheelhouse"
"${VENV_DIR}/bin/pip3" install --no-deps --no-index --force-reinstall ./*
Problem is, most (if not all) the time, environments differ drastically from one another. Developers may be on Windows, Mac or Linux, and CI runners are mostly Linux. On the final (app) execution environment, it may even be ARM-based. So, only executing pip download
without platform tags is insufficient. It’s not possible to focus on all environments, so for the most part I worry about the final environments the most (this means Linux, and x86_64/ARM).
For most of the projects I worked on, we implemented some sort of “package release train,” with the intention of providing a specific list of packages in specific pinned versions. This is extremely useful when provisioning lambda layers, EMR clusters and whatnot, and accelerates deployments by a great deal – on top of the previous restriction of no internet access, etc. But I need to enable the whole platform tag set. Updating the pip download
, this is what I imagine I could use, considering I know with certainty what is the final environment’s platform:
# Again, this is just an example.
# Why isn't this possible?
# More than one wheelhouse will be created, one for each combination of platform flags.
PROJECT_ROOT="$(pwd)"
cd "${PROJECT_ROOT}"
mkdir -p dist/wheelhouse
pip3 download \
-d dist/wheelhouse \
--implementation cp \
--python-version 37 \
--abi cp37m \
--platform manylinux2014_x86_64
Alas, this gives me an error:
ERROR: When restricting platform and interpreter constraints using --python-version, --platform, --abi, or --implementation, either --no-deps must be set, or --only-binary=:all: must be set and --no-binary must not be set (or must be set to :none:).
I would prefer to download only binary distributions, but the reality is that not all upstream dependencies provide one for the platforms I need. Also, most of the time, I’m unable to fix --only-binary=:all:
or --no-binary=:all:
, because some may be provided as source-only, others as binary-only, etc.
Regardless, why does it matter to pip that it downloads only binary distributions in this specific case? I imagine there’s absolutely no issue if I distribute both in the wheelhouse, as I won’t install them locally, and I know for sure I’ll be able to install the source distribution in the environment the wheelhouse is destined to be installed. Even [pip install --find-links
]( pip install - pip documentation v22.2.2 (pypa.io)) hints at this kind of support:
If a URL or path to an html file, then parse for links to archives such as sdist (.tar.gz) or wheel (.whl) files. If a local path or file:// URL that’s a directory, then look for archives in the directory listing. Links to VCS project URLs are not supported.
So, my question is: Is there any way or plan to support the download of mixed source-binary distributions in the case of a platform-specific resolution, via pip download
(or even pip wheel
)?