Hey, check out my Modern Python Projects course. It's an extended version of this workshop!

pipx

We solved the problem of separating dependencies between your projects. However, there are many great tools that you might want to use in many of your projects. For example, black - a code formatter, or flake8 - a linter (I will talk about them more in the next part of the workshop).

Let’s take a look at black - you run $ black some_python_file, and it will reformat this file to match a predefined set of style rules (use double quotes, don’t exceed 88 characters per line, etc.). This is a tool that you probably want to use for all your projects, so there is no point in installing it separately in each virtual environments. But you shouldn’t install it globally either. The more packages you install globally, the bigger the chance that some of their dependencies will conflict with each other.

Or maybe you want to run some Python package on your computer without actually installing it. You need it just this one time, so there is no point in keeping all the dependencies installed after that.

pipx - global packages in separate environments

This is where you might be interested in using pipx. It installs pip packages in separate environments, but at the same time, those packages act as if they were installed globally. You don’t need to activate any virtualenv to run them.

Install pipx with pip install pipx (or brew install pipx on macOS) and make sure that the PATH variable is updated by running pipx ensurepath command.

Now, each time you want to install a Python package on your computer (outside of a virtual environment specific to a project), do pipx install my_package instead of pip install my_package.

You can list your packages with:

$ pipx list
venvs are in /Users/YOUR_USERNAME/.local/pipx/venvs
apps are exposed on your $PATH at /Users/YOUR_USERNAME/.local/bin
   package black 19.10b0, Python 3.6.2
    - black
    - blackd
   package flake8 3.7.9, Python 3.6.2
    - flake8

And remove them with:

$ pipx uninstall my_package

With the pipx run command, you can run a command from the pip package in a temporary virtualenv that will be deleted after the command exits:

$ pipx run black my_file.py
⢿ installing package 'black'
reformatted my_file.py
All done! ✨ 🍰 ✨
1 file reformatted

You can even run a specific version of a package:

$ pipx run --spec black==18.3a1 black --version
black, version 18.3a1

pipx + VS Code

Remember when we installed flake8 linter when setting up VS Code? We installed it globally, but a much better way would be to use pipx and tell VS Code to use it:

  1. Install pipx
  2. Install flake8: pipx install flake8
  3. Find out the path to the flake8 binary:

    $ which flake8
    /Users/YOUR_USERNAME/.local/bin/flake8
    
  4. Tell VS Code to use that binary by setting the following value in settings.json file:
    "python.linting.flake8Path": "/Users/YOUR_USERNAME/.local/bin/flake8"