/ ubuntu

PEX - 自給自足的 Python 封裝格式

PEX 是一套能把 python 整個 virtual env 包裝成單一檔案的 python library,你可以很自由的透過 pip 安裝。然後寫一段簡略的 script 來包裝你現有的 python package,然後直接把這個 .pex (你也不一定要使用 .pex 後綴檔名) 搬到其他 Linux 環境,也是可以執行的,當然在新的環境上必須要有 Python interpreter。有點像是 portable 的 python script,不用考慮陷入某個 python package dependence 問題。

下面是 pex 的開發者所做的介紹,

也許有些人會考慮用另外一種封裝方式,像是直接透過 setuptools 包成 .deb, .egg or .whl,不過這些封裝方式都會遇到 package dependence 問題,有時候幫客戶解決這些問題的時間,都夠你重寫一套工具。加上有時候你需要的 python package 是在這個環境沒辦法取得的時候,整個就 gg 了。

如過透過 pyinstaller 也是整個封裝的另外一種方式。不過他是編譯之後轉換成不需要 python interpreter 的環境也可以執行。如果有在 Windows 執行需求的朋友,建議可以試試看。

因為目前 pex 支援的環境只有在 Linux 與 Mac(我測試過ok),當然手賤的我,一定嘗試在 Windows 上 build pex format 的檔案,其實是可以建立出來,不過似乎沒辦法直接執行,因為整個系統看不懂 pex 的格式。

所以目前採取的方式是透過 pex + .deb/.rpm 的方式來處理,因為

  • pex:解決 python package dependence 問題
  • .deb/.rpm: 解決安裝問題,因為全部封裝到 pex 裡面,所以不需要在 .deb/.rpm 處理 system package 問題

下面是簡單的範例,記得在執行前先建立一個 python virtual env,並透過執行 pip install pex,大致上可以安裝完成。

$ pip install pex
(pex)$ pex --disable-cache \
	-f ${PWD} \
	-r requirements.txt \
	${PWD} \
	-e mytest.mytest:main \
	-o dist/mytest.pex

執行完後,你會在 dist 目錄下找到 mytest.pex,你可以在有相同 Python interpreter 的 Linux 上執行。如過你需要再不同的 Python 版本中執行,建議在 build pex file 的時候指定 Python 版本。如有其他的需求,建議看看 pex --help

(pex) $ pex --python=python2.7 \
	... 

第一次執行 .pex 的時候,會發現他有點慢,其實他會在執行 user 的 home 目錄建立整個 virtual env 的(應該說是解壓縮),然後再執行 entry-point 的 module. 後面幾次執行,就不會有這些動作,整理跑起來沒有太多額外效能的影響。

最近有人在 reddit 問到這樣的問題 pex vs dh-virtualenv,如果有興趣的可以看看,我目前是透過 pex 跑起來沒有什麼太大問題,也許是我還沒遇到 How We Deploy Python Code 裡面所提到的狀況。

至於 dh-virtualenv,則是我還沒有測試過的工具,也許該找時間來看看。