PyCon 2018 之 Python 將來的依賴管理工具 pipenv

0x00 前言

PyCon 2018 有不少精彩的演講,今天的文章裏,介紹一下 K 神的演講 『Python 將來的包管理工具 pipenv』php

Kenneth Reitz 出品,必屬精品。vue

0x01 Python packaging 進化歷史

『上古時代』的 Pythonist 是這樣安裝依賴包的。node

curl http://pypi.python.org/packages/alsdasdl/requests.tar.gz | tar zxf
cd requests/
python setup.py install
複製代碼

這個問題初看起來不是問題,可是隨着你安裝程序的增多就知道有多麼痛苦了。python

  • 有的依賴庫依賴別的庫你怎麼解決?好比 pandas 須要安裝 numpy
  • 有的依賴庫依賴 c 庫怎麼辦?好比 LXML
  • 在 python2.6.5 下,若是我須要安裝兩個不一樣版本的 Django 開發不一樣的軟件怎麼辦?難道只能動態複製文件到 site-packages 裏面?

後來,咱們是這樣安裝包的。git

easy_install requests
複製代碼

咱們能夠直接從 pypi 進行安裝了。但尼瑪,爲何 easy_install 安裝很 easy, 可是沒有 easy_uninstall?github

好,2010 年後,咱們繼續前進:shell

  • 能夠經過 pip 替代 easy_install 了。
  • 能夠經過 virtualenv 管理項目的依賴庫了。雖說,仍是不能像 ruby gem 同樣同時把多個版本的的軟件裝在同一個系統裏。
  • 能夠經過 requirements 鎖依賴了。

但,同期的其餘編程語言社區分別出現了以下的包管理工具:npm

  • node -> yarn && npm , 有 lockfile
  • php -> composer , 有 lockfile
  • rust -> cargo , 有 lockfile
  • ruby -> bundler , 有 lockfile

而我大 Python 竟然沒跟上潮流django

python -> pip && virtualenv/venv , 無 lockfile編程

PS: Python3.3 以後,默承認以直接使用 venv 模塊,不須要再安裝 virtualenv 了。但仍是須要手動,而且用起來比較反直覺。

有人說,我能夠經過 requirements 來🔐版本呀

那咱們聊聊 requirements.txt

  • 若是你使用 pip freeze 來造成這個文件,則不直觀,徹底看不出來哪一個依賴庫依賴哪一個依賴。
  • 若是你直接手動指定你所須要的庫,好比 flask 的話,彷佛又有些太直觀了。
  • 若是能有一個東西,既能夠表示 freeze 的結果 (what you want),又能夠表示你須要的庫 (what you need). 就行了。

這固然能夠考慮用兩份 requirements 來解決。先安裝 what you need 用來開發,而後 freeze 爲 what you want 去部署。也就是最後生成 requirements-dev.txt , 而後最後 freeze 成 requirements-prod.txt

這其實仍是有一些能夠優化的地方的,鋪墊了這麼多 K 神確定是來介紹他的 pipenv 的。

好比說,我想查看,本項目的依賴庫,直接 pipenv graph

coverage==4.5.1
fabric==2.0.1
  - cryptography [required: >=1.1, installed: 2.2.2]
    - asn1crypto [required: >=0.21.0, installed: 0.24.0]
    - cffi [required: >=1.7, installed: 1.11.5]
      - pycparser [required: Any, installed: 2.18]
    - idna [required: >=2.1, installed: 2.6]
    - six [required: >=1.4.1, installed: 1.11.0]
  - invoke [required: <2.0,>=1.0, installed: 1.0.0]
  - paramiko [required: >=2.4, installed: 2.4.1]
    - bcrypt [required: >=3.1.3, installed: 3.1.4]
      - cffi [required: >=1.1, installed: 1.11.5]
        - pycparser [required: Any, installed: 2.18]
      - six [required: >=1.4.1, installed: 1.11.0]
    - cryptography [required: >=1.5, installed: 2.2.2]
      - asn1crypto [required: >=0.21.0, installed: 0.24.0]
      - cffi [required: >=1.7, installed: 1.11.5]
        - pycparser [required: Any, installed: 2.18]
      - idna [required: >=2.1, installed: 2.6]
      - six [required: >=1.4.1, installed: 1.11.0]
    - pyasn1 [required: >=0.1.7, installed: 0.4.2]
    - pynacl [required: >=1.0.1, installed: 1.2.1]
      - cffi [required: >=1.4.1, installed: 1.11.5]
        - pycparser [required: Any, installed: 2.18]
      - six [required: Any, installed: 1.11.0]
flake8==3.5.0
  - mccabe [required: >=0.6.0,<0.7.0, installed: 0.6.1]
  - pycodestyle [required: <2.4.0,>=2.0.0, installed: 2.3.1]
  - pyflakes [required: >=1.5.0,<1.7.0, installed: 1.6.0]
# 其餘省略
複製代碼

假如我要檢查我當前開發環境的依賴是否是有些小問題。直接執行 check

$ pipenv check
Checking PEP 508 requirements…
Passed!
Checking installed package safety…

33075: django >=1.10,<1.10.3 resolved (1.10.1 installed)!
Django before 1.8.x before 1.8.16, 1.9.x before 1.9.11, and 1.10.x before 1.10.3, when settings.DEBUG is True, allow remote attackers to conduct DNS rebinding attacks by leveraging failure to validate the HTTP Host header against settings.ALLOWED_HOSTS.

33076: django >=1.10,<1.10.3 resolved (1.10.1 installed)!
Django 1.8.x before 1.8.16, 1.9.x before 1.9.11, and 1.10.x before 1.10.3 use a hardcoded password for a temporary database user created when running tests with an Oracle database, which makes it easier for remote attackers to obtain access to the database server by leveraging failure to manually specify a password in the database settings TEST dictionary.

33300: django >=1.10,<1.10.7 resolved (1.10.1 installed)!
CVE-2017-7233: Open redirect and possible XSS attack via user-supplied numeric redirect URLs
============================================================================================

Django relies on user input in some cases  (e.g.
:func:`django.contrib.auth.views.login` and :doc:`i18n </topics/i18n/index>`)
to redirect the user to an "on success" URL. The security check for these
redirects (namely ``django.utils.http.is_safe_url()``) considered some numeric
URLs (e.g. ``http:999999999``) "safe" when they shouldn't be. Also, if a developer relies on ``is_safe_url()`` to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack. CVE-2017-7234: Open redirect vulnerability in ``django.views.static.serve()`` ============================================================================= A maliciously crafted URL to a Django site using the :func:`~django.views.static.serve` view could redirect to any other domain. The view no longer does any redirects as they don't provide any known, useful
functionality.

Note, however, that this view has always carried a warning that it is not
hardened for production use and should be used only as a development aid.
複製代碼

如未嘗鮮?我最近更新到了以前寫的一個庫(代碼寫的慘不忍賭,最近準備重構,勿噴)

git clone git@github.com:twocucao/YaPyLib.git
cd YaPyLib/
brew install pipenv
pipenv --three
pipenv install --dev
pipenv shell
複製代碼

記住幾個命令

pipenv --venv # 查看 venv 位置
pipenv --python 3.6.5
exit 退出 pipenv shell
複製代碼

當進入項目的時候,就執行 pipenv shell 自動 source 一下環境。嗯,但總以爲假如我維護了 30 個項目,每次開一個終端 cd 到對應的目錄,而後執行 pipenv shell 真的很麻煩啊。

嗯,沒錯,要是能將這個過程自動化就行了。

本人假設你用的 zsh , 添加下面的配置到 zsh 中。

function auto_pipenv_shell {
    if [ ! -n "${PIPENV_ACTIVE+1}" ]; then
        if [ -f "Pipfile" ] ; then
            pipenv shell
        fi
    fi
}

function cd {
    builtin cd "$@"
    auto_pipenv_shell
}

auto_pipenv_shell
複製代碼

至於其餘的功能,參考官網本身摸索吧。

FAQ 環節

FAQ 環節有一個問題很是有趣,應該把 lockfile 放在 git 倉庫裏面嗎?

k 神是這麼回答的 yes。 這個問題好久以前就在 issue 上回答過了

https://github.com/pypa/pipenv/issues/598

我剛開始以爲不提交會好一些,後來以爲 track 一下也無妨。

寫在最後

在用 npm / yarn 寫 node 程序 /vuejs 應用的時候,特別但願 python 圈子裏面能出一個相似於包管理工具。後來果真有了 pipenv, 今年 2 月份的時候把本身的項目遷移過來,發現 pipenv 用起來很挺舒服的。

pipenv 是 Python 將來的依賴管理工具。火速用上吧。

相關文章
相關標籤/搜索