0 x00 preface

In PyCon 2018, there are a lot of interesting talks. Today’s article is about “The future of Python package management tool Pipenv”.

Kenneth Reitz. It’s a must.

0x01 Python Packaging Evolutionary history

This is how Pythonist of “ancient times” installs dependency packages.

curl http://pypi.python.org/packages/alsdasdl/requests.tar.gz | tar zxf
cd requests/
python setup.py install
Copy the code

This may not seem like a problem at first, but it becomes more painful as you install more programs.

  • How do you deal with dependencies that depend on other libraries? For example, PANDAS requires the installation of NUMpy
  • What if some dependent libraries depend on C library? Such as LXML
  • Under python2.6.5, what if I need to install two different versions of Django to develop different software? Can only dynamically copy files to site-packages?

Later, we installed packages like this.

easy_install requests
Copy the code

We can install directly from pYPI. But hell, why is easy_install easy to install, but no easy_uninstall?

Well, after 2010, we move on:

  • PIP can now be used instead of easy_install.
  • Virtualenv is now available to manage your project’s dependent libraries. However, it is still not possible to install multiple versions of software on the same system as Ruby Gem does.
  • You can now rely on the requirements lock.

However, the following package management tools have emerged in other programming language communities over the same period:

  • Node -> yarn && NPM, with lockfile
  • PHP -> composer with lockfile
  • Rust -> cargo, has lockfile
  • Ruby -> Bundler, lockfile

And I’m not keeping up with the trend

Python -> PIP && virtualenv/venv, no lockfile

PS: After Python3.3, the venv module can be used directly by default without the need to install virtualenv. But it’s still manual, and it’s a little counter-intuitive to use.

Some people say, I can go through requirements to 🔐

So let’s talk about requirements.txt

  • If you use PIP Freeze to form this file, it is not intuitive to see which dependency library depends on which dependency.
  • If you manually specify the libraries you need, such as flask, it seems a little too intuitive.
  • If you can have one thing that represents both the result of a freeze (what you want) and the library you need (what you need). It’ll be ok.

This can of course be considered with two requirements. Install what You need for development, and freeze for what you want to deploy. Create requirements-dev. TXT and freeze to requirements-prod. TXT

There are a few things that can be optimized, and with all this setup The King must have come to introduce his Pipenv.

So, for example, I want to look at this project’s dependency library, the direct 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]# other ellipses
Copy the code

Let’s say I want to check if there are any minor issues with my current development environment dependencies. Execute check directly

$PIpenv check Checking PEP 508 requirements... Passed! Checking the 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 passwordfor 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 inThe 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 inputin 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.
Copy the code

How to taste something new? I recently updated a library I wrote earlier.

git clone [email protected]:twocucao/YaPyLib.git
cd YaPyLib/
brew install pipenv
pipenv --three
pipenv install --dev
pipenv shell
Copy the code

Remember a few commands

pipenv --venv # Check venv locationPipenv - python 3.6.5exitExit pipenv shellCopy the code

When entering the project, the Pipenv shell automatically source the environment. Yeah, but I always felt like if I was maintaining 30 projects, it would be really cumbersome to open a terminal CD to the corresponding directory and execute the Pipenv shell at a time.

Well, yes, it would be nice to automate the process.

I assume you are using ZSH, add the following configuration to 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
Copy the code

As for other functions, refer to the official website to explore it.

The FAQ link

An interesting question in the FAQ section is, should I put lockfile in git repository?

K god answered yes. This question was answered on Issue a long time ago

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

At first, I thought it would be better not to mention it, but then I thought it wouldn’t hurt to track it.

Write in the last

When writing node programs /vuejs applications using NPM/YARN, we hope that there is a package management tool in python. Later, PIPENV was born. In February this year, I migrated my project here and found that PIpenV is very comfortable to use.

Pipenv is the dependency management tool of the future for Python. Use it quickly.