-
This discussion is forked from pypa/pip#11664 (comment) |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 3 replies
-
Pex is definitely not a drop-in for Pip - its primary use case revolves around shipping whole environments in a single zipapp (PEX) file; so depending on what you need to accomplish it may or may not work for your needs. If you exactly need to ship the distributions (sdists and wheels) needed by a foreign platform, Pex won't work. If you just need to ~pre-build a venv for a foreign target, that can work. For example, running on Linux x86-64 and targeting Linux aarch64: # Characterize the foreign platform target - a 1 time operation:
:; docker run --rm -it --platform linux/aarch64 python:3.13 bash -c 'pip -q install --root-user-action ignore pex && pex3 interpreter inspect --markers --tags' > linux-aarch64-complete-platform.json
# Now use the foreign target platform description to resolve a hermetic environment for it:
:; cat <<EOF > requirements.txt
cowsay
psutil
EOF
:; pex -r requirements.txt --complete-platform linux-aarch64-complete-platform.json --venv -o example.pex
:; zipinfo example.pex | grep METADATA
?rw-r--r-- 2.0 unx 5581 b- defN 80-Jan-01 00:00 .deps/cowsay-6.1-py3-none-any.whl/cowsay-6.1.dist-info/METADATA
?rw-r--r-- 2.0 unx 22315 b- defN 80-Jan-01 00:00 .deps/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl/psutil-7.0.0.dist-info/METADATA
:; python -c 'import os; print(os.uname())' && docker run --rm -it --platform linux/aarch64 -v $PWD/example.pex:/example.pex python:3.13 /example.pex -c 'import cowsay, psutil, os; cowsay.tux(f"{psutil.Process()}\n{os.uname()}")'
posix.uname_result(sysname='Linux', nodename='gill-xps', release='6.14.0-22-generic', version='#22-Ubuntu SMP PREEMPT_DYNAMIC Wed May 21 15:01:51 UTC 2025', machine='x86_64')
_________________________________________________
/ \
| psutil.Process(pid=1, name='python', status='runn |
| ing', started='23:00:07') |
| posix.uname_result(sysname='Linux', nodename='4fa |
| a4504fcbb', release='6.14.0-22-generic', version= |
| '#22-Ubuntu SMP PREEMPT_DYNAMIC Wed May 21 15:01: |
| 51 UTC 2025', machine='aarch64') |
\ /
=================================================
\
\
\
.--.
|o_o |
|:_/ |
// \ \
(| | )
/'\_ _/`\
\___)=(___/ |
Beta Was this translation helpful? Give feedback.
-
Cool, thanks! I think what I was missing is that I can unzip the |
Beta Was this translation helpful? Give feedback.
-
So, I was hoping you'd explain your use case a bit more. Do you actually need wheels? Many use cases just need a venv to run something in, and the intermediate products of wheels or sdists to build the venv with are incidental. That said - if you do really need wheels: :; docker run --rm -it --platform linux/aarch64 -v $PWD/example.pex:/example.pex python:3.13 bash -c 'PEX_TOOLS=1 /example.pex repository extract --dest-dir ./wheels && ls -l ./wheels/'
cowsay 6.1: Repacking wheel as /wheels/cowsay-6.1-py3-none-any.whl...OK
psutil 7.0.0: Repacking wheel as /wheels/psutil-7.0.0-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl...OK
total 304
-rw-r--r-- 1 root root 26362 Jun 25 16:15 cowsay-6.1-py3-none-any.whl
-rw-r--r-- 1 root root 279709 Jun 25 16:15 psutil-7.0.0-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl Or, if you want a traditional venv instead of a PEX file: :; docker run --rm -it --platform linux/aarch64 -v $PWD/example.pex:/example.pex python:3.13 bash -c 'PEX_TOOLS=1 /example.pex venv --pip ./.venv && ./.venv/bin/pip list'
Package Version
------- -------
cowsay 6.1
pip 25.1.1
psutil 7.0.0 N.B.: That neither of the prior exercises uses the network. All code and artifacts are self-contained in the PEX zip file to do all this. |
Beta Was this translation helpful? Give feedback.
-
My organization, and the defense community at large, use several air-gapped networks to isolate and compartmentalize sensitive data. We have set up self-hosted package indexes on some of these intranets, where we want to mirror select approved packages from PyPI, as well as distribute some internally-developed packages. Each air-gapped network has it's own environment, often Anaconda, often Windows, and anywhere up to 5 years out of date - although other platforms are getting more popular through some of our self-hosted web IDEs, VMs, and containerized apps. The only way to bring data onto an air-gapped network is a one-way file transfer on disposable media. Usually burning a CD from an internet-connected computer, getting it approved by security, transferred by an administrator, then shredded. There is virtually no approved way to get anything off an air-gapped network and back to anything internet-connected. All for good reason - security is the game. The way we currently collect packages to transfer is by keeping a for platform in win_amd64 manylinux2014_x86_64; do
for version in 3.8 3.9 3.10 3.11 3.12; do
pip download \
-r requirements.txt \
--dest=dist \
--only-binary=:all: \
--platform=$platform \
--python-version=$version
done
done But this runs into problems with sdist packages (or any package that has sdist dependencies), and any packages that use environment markers. It also assumes that users are within this subset of environments, which is generally a safe assumption but not necessarily true. |
Beta Was this translation helpful? Give feedback.
-
With the release of Pex 2.41.0 I'll mark this as answered. That release supports |
Beta Was this translation helpful? Give feedback.
With the release of Pex 2.41.0 I'll mark this as answered. That release supports
pex3 download
directly allowing 1st class support for downloading distributions needed by foreign platforms via--platform
or--complete-platform
.