Shell Scripts for Virtual Python Environments

Ian Hellström | 6 March 2020 | 2 min read

Python development without virtual environments is a pain; with virtual environments it quickly gets messy. Here is a shell script to make life with Python easier.

Below are the functions I have added in a script that’s sourced by the shell:

#!/bin/bash
__PY_ENVS__="$HOME/Python"

function py() {
  local environment="${1:-default}"
  if [ -d "${__PY_ENVS__}/${environment}" ]; then
  	source "${__PY_ENVS__}/${environment}/bin/activate" && which python3
  else
  	echo "Sorry, but ${environment} does not yet exist."
  	echo "Please create it with   pyenv ${environment}   first."
  fi
}

function pyenv() {
  local environment="${1:-default}"
  if [ -d "${__PY_ENVS__}/${environment}" ]; then
  	echo "Sorry, but ${environment} already exists."
  	echo "Please activate it with   py ${environment}   instead."
  else
    python3 -m venv "${__PY_ENVS__}/$environment" && \
      py "${environment}" && \
      pip3 install --upgrade pip && \
      pip3 install black
  fi
}

function pipins() {
  pip3 install -r "${1:-requirements.txt}"
}

function pyenvs() {
  ls "${__PY_ENVS__}"
}

function nopyenv() {
  local environment="$1"
  if [ -d "${__PY_ENVS__}/${environment}" ]; then
    rm -rf "${__PY_ENVS__}/${environment}"
  else
    echo "Sorry, but ${environment} does not exist."
    echo "The following environments are available:"
    pyenvs
  fi
}

All virtual environments live in ~/Python. The default environment is called default and it can be activated with py.

How to…

Create a New Environment

If you want to set up a new enviroment, you can simply execute pyenv my_new_env. It sets up a Python 3 environment to which you can install library dependencies as needed. I automatically add Black, because most projects I have worked with assume you have a formatter already on your machine, although it is rarely listed in the requirements file and therefore not installed when you run pipins.

What’s pipins? When you run pipins requirements.txt, the shell will install all the packages defined in requirements.txt in the virtual environment. The default argument is requirements.txt, so you can also leave it off.

Activate an Existing Environment

For an environment you have already set up, run py my_existing_env and it will be active in the terminal. Note that the default environment has to be created before you can use it. A single execution of pyenv suffices.

In IntelliJ, PyCharm, or whatever IDE you prefer, you may have to point your project to that specific virtual environment to ensure there is a Python SDK available.

Remove an Existing Environment

With nopyenv my_obsolete_environment you delete the environment altogether.

List All Environments

To list all existing environments you use pyenvs.

Notes

If you have a company-internal index for Python packages, you can add the following to the pipins function:

--trusted-host "${__PY_HOST__}" --extra-index-url "${__EXTRA_INDEX_URL__}"

Of course you first have to define both __HOST__ and __EXTRA_INDEX_URL__.

If you have set HTTP(S)_PROXY variables, you may have to add

export NO_PROXY="${__PY_HOST__}"

in your profile to ensure the host on the company’s internal network is not accessed through a proxy.