Skip to content

Instantly share code, notes, and snippets.

@dbtek
Last active December 15, 2024 08:56
Show Gist options
  • Save dbtek/fb2ddccb18f0cf63a654ea2cc94c8f19 to your computer and use it in GitHub Desktop.
Save dbtek/fb2ddccb18f0cf63a654ea2cc94c8f19 to your computer and use it in GitHub Desktop.
Python 3 venv wrapper. Manages all virtual environments under ~/.venv/ .
# venv_wrapper, manage all virtual environments under ~/.venv/
# Include the following in .bashrc / .bash_profile / .zshrc
# See https://gist.github.com/dbtek/fb2ddccb18f0cf63a654ea2cc94c8f19
#
# Usage:
# $ mkvenv myvirtualenv # creates venv under ~/.venv/
# $ venv myvirtualenv # activates venv
# $ deactivate # deactivates venv
# $ rmvenv myvirtualenv # removes venv
# $ rmvenv env1 env2 # removes multiple venvs
# $ lsvenv # lists all venvs
export VENV_HOME="$HOME/.venv"
[[ -d $VENV_HOME ]] || mkdir -p $VENV_HOME
lsvenv() {
ls -1 "$VENV_HOME"
}
venv() {
if [ $# -eq 0 ]; then
echo "Please provide venv name"
elif [ -d "$VENV_HOME/$1" ]; then
source "$VENV_HOME/$1/bin/activate"
else
echo "Virtual environment '$1' does not exist."
fi
}
mkvenv() {
if [ $# -eq 0 ]; then
echo "Please provide venv name"
else
if [ -d "$VENV_HOME/$1" ]; then
echo "Virtual environment '$1' already exists."
else
echo "Creating venv under $VENV_HOME/$1"
python3 -m venv "$VENV_HOME/$1"
echo "Activating $1"
venv "$1"
fi
fi
}
rmvenv() {
if [ $# -eq 0 ]; then
echo "Please provide one or more venv names"
else
current_venv=$(basename "${VIRTUAL_ENV:-}")
for env in "$@"; do
if [ -d "$VENV_HOME/$env" ]; then
if [ "$env" = "$current_venv" ]; then
deactivate
echo "Deactivated current virtual environment '$env'."
fi
rm -rf "$VENV_HOME/$env"
echo "Virtual environment '$env' removed."
else
echo "Virtual environment '$env' does not exist."
fi
done
fi
}
complete -C lsvenv venv
complete -C lsvenv rmvenv
@maxwellmckinnon
Copy link

maxwellmckinnon commented Jul 8, 2019

This is great thanks. You might want to add protection against rmvenv with no argument given, so that someone doesn't blow away all their environments :)

@dbtek
Copy link
Author

dbtek commented Jul 8, 2019

@maxwellmckinnon you are absolutely right. Any suggestions?

@dbtek
Copy link
Author

dbtek commented Jul 9, 2019

Updated gist with no argument checks. Thanks to maxwellmckinnon.

@Parth576
Copy link

So glad I found this when I searched for "venv wrapper", works perfectly. Thanks!

@zekefarwell
Copy link

Thanks for this! I found it handy to add an lsvenv command as well to list the existing virtual environments under ~/.venv/

lsvenv() {
  ls -1 $VENV_HOME
}

@dbtek
Copy link
Author

dbtek commented Aug 13, 2020

Thanks @zekefarwell. Added lsvenv.

@leoschmitz
Copy link

Useful gist 👍 . I added complete -W "`lsvenv`" venv to the end of it so venv can autocomplete with the tab key. It might help you out.

@kuirolo
Copy link

kuirolo commented Mar 29, 2022

This is great! My system version is 3.10 which tends to break things, so I added a few lines so mkvenv can optionally set the version. It's a bit fragile and basic, but it works for my purposes.

mkvenv() {
  if [ $# -eq 0 ]
    then
      echo "Please provide venv name"
  elif [ $# -eq 1 ]
    then
      python3 -m venv $VENV_HOME/$1
  elif [ $# -eq 2 ]
    then
      python$2 -m venv $VENV_HOME/$1
  fi      
}

@billyzs
Copy link

billyzs commented Sep 23, 2022

the ZSH equivalent for @leoschmitz 's one liner above is
compdef '_path_files -/ -W $VENV_HOME' venv

@dbtek
Copy link
Author

dbtek commented Jan 22, 2024

Autocompletion added for venv and rmvenv commands. Thanks @leoschmitz, @billyzs.
Auto activating newly created venv with mkvenv is also added along with some informative messages.

@dbtek
Copy link
Author

dbtek commented Jul 2, 2024

Changes and Improvements:

Error Checking:

  • Added mkdir -p $VENV_HOME to ensure the directory structure is created if it doesn't exist.
  • Added checks to ensure that the virtual environment exists before attempting to activate or remove it.

User Feedback:

  • Added feedback messages to inform the user about the creation and deletion of virtual environments.

Multiple Environment Deletion:

  • Enhanced rmvenv function to accept multiple arguments, allowing deletion of multiple virtual environments in a single command.
  • Added loop in rmvenv to iterate over all provided virtual environment names, checking for their existence and deleting them if they exist.

Deactivation Before Deletion:

  • Added logic to deactivate the currently active virtual environment if it is one of the environments being deleted.

Improved Comments:

  • Enhanced script comments for better clarity and understanding of usage.

@andy-maier
Copy link

I created the venvwrapper package on Pypi which provides an improved version of this script.

At this point, the venvwrapper package supports bash and zsh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment