轉自:http://codingpy.com/article/a-better-pip-workflow-recommended-by-kenneth/
現在大家開發Python應用時,在代碼庫的根目錄中添加一個
requirements.txt
檔案已經成了标準實踐。
這個檔案用處挺多,一般有以下兩種形式:
- 項目的頂層依賴包清單(top-level dependencies),通常不會指定版本号
- 項目的全部依賴包清單,每個依賴包都指定版本号
方法1:簡單的 requirements
檔案
requirements
項目的頂層依賴包清單,通常不會指定版本号。
$ cat requirements.txt
requests[security]
flask
gunicorn==19.4.5
方法1非常簡單,也是每個使用
requirements
檔案的開發者希望獲得的使用者體驗。但是,如果将這樣一個
requirements.txt
檔案部署到生産環境,有可能會出現預料之外的問題。因為你沒有指定版本号,是以在運作
pip install
後,你今天安裝的Python包可能和明天安裝的就會不一樣。
這是很糟糕的。因為子依賴包可能經常更新版本号,是以重新運作
pip install -r requirements.txt
可能會讓你安裝不一樣的Python包。這有可能會讓你的應用因為未知的原因而無法運作。
方法2:精确的 requirements
requirements
$ cat requirements.txt
cffi==1.5.2
cryptography==1.2.2
enum34==1.1.2
Flask==0.10.1
gunicorn==19.4.5
idna==2.0
ipaddress==1.0.16
itsdangerous==0.24
Jinja2==2.8
MarkupSafe==0.23
ndg-httpsclient==0.4.0
pyasn1==0.1.9
pycparser==2.14
pyOpenSSL==0.15.1
requests==2.9.1
six==1.10.0
Werkzeug==0.11.4
方法2是部署應用時應采取的最佳實踐,可以確定你的運作環境不會出現問題。
所有的依賴包,包括子依賴包都明确列出,而且指定了各自的版本号。
這種類型的
requirements.txt
是在應用目前工作運作環境下,運作
pip freeze
指令自動生成的。這種做法鼓勵開發者平等對待開發/生産環境(dev/prod parity),對待外部依賴包,就像對待本身應用的代碼一樣尊敬(因為它們也是你應用代碼的一部分)。
麻煩之處
盡管方法2是使用
requirements.txt
的最佳實踐,但實際上還是有點麻煩。舉個例子,如果我有一個較大的代碼庫,希望通過
pip install --upgrade
指令更新部分或全部Python包,我沒有辦法輕松地做到這點。
之前我的方法是,一個一個地把頂層的依賴包挑出來,然後手動輸入
pip install requests[security] flask --upgrade
。這個過程可不好受。
我思考了很久,還想過要開發一個工具來解決這個問題。當然,現在已經有了像
pip-tools
這樣的工具。可是,我不想再往自己的工具鍊(tool chain)裡加東西了;這個問題應該利用已有的工具就能解決。
最後,我想出了一個很好的方案,利用我現有的工具解決了這個問題,而且兼具方法1和方法2的優勢。我已經在項目中使用這個工作流一段時間,對結果非常滿意。
工作流
其實很簡單:我們不隻放一個
requirements
檔案,而是兩個:
- requirements-to-freeze.txt
- requirements.txt
requests[security]
flask
gunicorn==19.4.5
cffi==1.5.2
cryptography==1.2.2
enum34==1.1.2
Flask==0.10.1
gunicorn==19.4.5
idna==2.0
ipaddress==1.0.16
itsdangerous==0.24
Jinja2==2.8
MarkupSafe==0.23
ndg-httpsclient==0.4.0
pyasn1==0.1.9
pycparser==2.14
pyOpenSSL==0.15.1
requests==2.9.1
six==1.10.0
Werkzeug==0.11.4
requirements-to-freeze.txt
遵循的是方法1,檔案中說明了項目的頂層依賴包,以及你需要指定的明确版本号。
requirements.txt
遵循的是方法2,其中的内容是運作
pip install requirements-to-freeze.txt
指令後,
pip freeze
生成的。
基本用法
$ cd project-repo
$ pip install -r requirements-to-freeze.txt --upgrade
Installing collected packages: six, enum34, ipaddress, ...
$ pip freeze > requirements.txt