在離線環境安裝 Python 套件
1 |
五花八門應有盡有的套件是 Python 好用的關鍵之一,在 Python 要安裝套件很簡單,只需 pip install <package-name>
一行指令,pip 工具會查詢 Python Package Index (PyPI) 依據當前 Python 版本、作業系統、CPU 架構找出適用的套件檔,連同本機還沒安裝的相依套件一起下載安裝,連小學生都會。
但 pip install <package-name>
無腦安裝的前題是必須連上網際網路,要無法上網的封閉環境要安裝套件,便需要學會離線安裝 Python 套件的技能。
做法不難,先在可連網環境執行 pip download <package-name>
(或加 --dest <save-path>
指定下載儲存路徑),pip 會下載該套件所需的相關檔案(例如:.whl,平台專屬的二進位 Wheel 文件) ,將檔案複製到與世隔絕的主機上,再用指令 pip install <package-name> --no-index --find-links <path-to-package-files>
(no-index 表不查詢 PyPI,find-links 指定套件檔來源),即可在離線環境安裝 Python 套件。
補充幾個延伸議題。
平台架構與Python 版本
最常見的套件檔格式是 .whl,它是針對特定平台編譯好的二進位程式庫,可直接執行。但不同 Python 版本、作業系統、CPU 架構有不同的 .whl 檔,通常可由檔名識別。以 Numpy 為例,針對不同 OS 及 Python 版本便有不同的下載檔:
numpy-2.1.0-pp310-pypy310_pp73-win_amd64.whl
- Python 3.10, Windows x86/64numpy-2.1.0-cp312-cp312-macosx_14_0_x86_64.whl
- Python 3.12, macOS 14+ x86/64numpy-2.1.0-cp312-cp312-macosx_14_0_arm64.whl
- Python 3.12, macOS 14+, ARMnumpy-2.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Python 3.11, Linux glibc 2.17+ x86/64
最簡單的做法是準備一台跟部署對象 CPU 架構、作業系統與 Python 版本都相同的電腦或 Docker 容器,在上面用 pip download <package-name>
無腦下載就好了。
從不同平台下載
若沒有相同的環境,下載時也可透過 --platform
、--python-version
指定特定平台或版本,但狀況會複雜些。
若不確定目標主機的 platform 參數,在目錄平台執行 pip debug --verbose
可找到線索:
pip debug 資料最後有一長串 Comptable tags 清單,項目最後一截是可相容的平台識別字串,細到每個 OS 版本一筆 [1]。而以 numpy 為例,若用相容標籤比對,吻合的會是 cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64
,因此,隨便輸入 --platform manylinux_2_35_x86_64
不行 [2],必須要輸入 --platform manylinux_2_17_x86_64
才能找到 [3]。
--platform
參數不支援 * 萬用字元,但支援輸入多筆。由於不確版套件提供的版本會與相容清單的哪一項吻合,一個解法是把所有相容選項都列上去讓 pip 去比對,用一段 PowerShell 來實現:
$pipDebug = (& pip debug --verbose) -join "`n"
$pipDebug -match "(?ims)Compatible tags:(.*)"
([Text.RegularExpressions.Regex]::Matches($matches[1], '(\S+)\-(\S+)\-(?<p>\S+)') | ForEach-Object {
'--platform ' + $_.Groups['p'].Value
} | Select-Object -Unique) -join ' '
以上 PowerShell 程式在 Ubuntu 22.04 執行 (對,PowerShell、.NET 都可在 Linux/macOS 跑,下回聽到有人 .NET 只能用在 Windows,記得衝上去大力搖醒他 😛) 可得到 --platform manylinux_2_35_x86_64 --platform manylinux_2_34_x86_64 --platform manylinux_2_33_x86_64 --platform manylinux_2_32_x86_64 --platform manylinux_2_31_x86_64 --platform manylinux_2_30_x86_64 --platform manylinux_2_29_x86_64 ... --platform manylinux_2_5_x86_64 --platform manylinux1_x86_64 --platform linux_x86_64 --platform any
這樣的長串文字。
將它接在 pip download
後當參數,便能在 Windows 11 為 Ubuntu 22.04 Python 3.10 成功下載 Linux 用的 numpy 套件檔囉~
同場加映,bash 版 --platform 清單產生器:
pipDebug=$(pip debug --verbose)
if [[ $pipDebug =~ Compatible\ tags:\ (.*) ]]; then
platforms=$(echo "${BASH_REMATCH[1]}" | grep -oP '\S+-\S+-(\K\S+)' | sort -u | sed 's/^/--platform /' | tr '\n' ' ')
echo "$platforms"
fi
編譯問題
除了 .whl/.egg 這類編譯好的套件,有些套件提供的是原始碼,pip 下載後會嘗試編譯出二進位檔(前題是已安裝所需的編譯工具),此時手續會複雜很多。直接說結論:準備一台跟目標主機相同的環境比較快,別浪費生命。但如果你有興趣了解更多,可參考這篇離線安裝 TensorFlow 套件心得。
The blog explains how to install Python packages offline using pip download to fetch necessary files in a connected environment and then pip install --no-index --find-links to install them in an offline environment. It also covers challenges with platform-specific packages and provides scripts to handle platform compatibility.
Comments
# by Joker
優秀,金融業相當有用,感謝分享。