Package: envie
Envieis a set of shell utilities (inbash) aiming to increase your productivity
when dealing with mundane Python virtual environment tasks, like creating, destroying,
listing/discovering, and switching/activating environments.Where Envie really shines is auto-discovery, auto-activation and auto-creation of
virtual envs relevant to your project (or executable). It holds no assumptions on
virtual env dir location in relation to your code (or working directory),
but works best if they’re near (nested, in level, or a few levels up).MotivationI like to keep my virtual environments close to source (especially in production).
With hundreds of projects on disk, this enables me to keep environment dir names short
and project-relevant (since a project can have several environments, e.g. dev, prod, test).
Also, environments are easy to locate, update, or rebuild (maintain in general).If you structure your files/projects in any of the ways depicted in Fig 1. below, you’ll
find Envie particularly helpful.work                            work                                /srv
│                               │                                   │
├── plucky                      ├── jsonplus                        ├── production
│   ├── env       <--           │   ├── .git                        │   ├── website
│   ├── plucky                  │   ├── django                      │   │   ├── pythonenv     <--
│   ├── tests                   │   │   ├── env                     │   │   ├── var
│   └── ...                     │   │   │   ├── dev      <--        │   │   └── src
│                               │   │   │   └── prod     <--        :   :       ├── .git
├── blog                        │   │   ├── tests                   :   :       └── ...
│   ├── .env      <--           │   │   │   ├── env      <--        .   .
:   ├── .git                    :   :   :   ├── test_1.py
:   ├── _posts                  :   :   :   └── ...
.   └── ...                     .   .   .

(a) env in level with src       (b) env nested under src           (c) env one level above src

Figure 1. Several ways to keep your environments local to the code.Easy activationTo activate the closest virtual environment in vicinity, just typeenvie(Fig 1.a and 1.c):~/work/plucky$envieActivatedvirtualenvironmentat'env'./srv/production/website/src$envieActivatedvirtualenvironmentat'../pythonenv'.If several equally close environments are found (Fig 1.b), you’ll be prompted to select
the exact env. But, you can avoid it with a cunning use offuzzy-filtering, for example:~/work/jsonplus$enviedevActivatedvirtualenvironmentat'django/env/dev'.Discovery and filtering have no limits on depth, so you can activate your project environment like:~$envieplusdevActivatedvirtualenvironmentat'work/jsonplus/django/env/dev'.Implicit activationSometimes you don’t care about activating the relevant environmentin your shell.
You just want your script to run in the correct env. Easy peasy (ref. Fig 1.b):~/work/jsonplus$envie./django/tests/test_1.pyActivatedvirtualenvironmentat'django/tests/env'.# running test ...It doesn’t have to be a Python script:~/work/plucky$envierunmaketestActivatedvirtualenvironmentat'env'.# running 'make' with python from envAnd it works from a hash bang too:#!/usr/bin/env envieYou can even activate the closest environment after the fact, from your Python program
(changing the environment from whatever was current — to the closest, relative to the script):#!/usr/bin/pythonimportenvie.activate_closestTerse & pip-infused createSure, you can usevirtualenv--python=python3env, but isn’t this simpler?$enviecreate-3# or, shorter:$mkenv3And how about alsoinstallingyourpip requirementsin one go?$mkenv-rdev-requirements.txtenv/devOr, creating atemporary/throw-awayenvironmentwithsomepackagesinstalled, then
hacking in an interactive Python session, and finally destroying the complete environment upon exit:$mkenv-t-prequests-p'plucky>=0.4'&&python&&rmenv-fDetails and more examples are available inenvie create,envie remove, andenvie-tmpdocs.Existing environments discoveryActivation of the closest environment is predicated on the discovery of the existing virtual
environments below a certain directory withlsenv(envie list), and on the up-the-tree
search withfindenv(envie find):~/work$lsenvplucky/envblog/.envjsonplus/django/env/dev...Install & configureFor convenience,envieis packaged and distributed as a Python package.
You can install it system-wide (or user-local, seeInstalldocs):$sudopipinstallenvie$envieconfig# don't forget to source envie:$.~/.bashrc# or just open a new shellAfter install, be sure to run a (short and interactive)configurationprocedure withenvie config.
If in doubt, go with the defaults. Running config is optional, but recommended.
It’ll, for example, allow to you easily add Envie sourcing statement to your.bashrc(enabling Bash completion and alias functions), and to activate environments indexing
(enabling faster search withlocate).Enable indexBy default,envieuses thefindcommand to search for environments. That
approach is pretty fast when searching shallow trees. However, if you have
deeper directory trees, it’s often faster to use a pre-built directory index
(i.e. thelocatecommand). To configure a combinedlocate/findapproach to
search, runenvie config.When index is enabled, the combined approach is used by default (if not overriden with-for-lswitches). In the combined approach,findandlocatestart searching
in parallel and vie for producing results first. However,findis given only 400ms to finish
before being terminated, thusly producinglocate-based results for deeper trees faster
(but potentially incomplete if index was stale).TestingRun all test suites locally with:$ make test(after cloning the repo.)Usage in shortenvie[-1][-f|-l][<basedir>] [<keywords>](aliaschenv)Interactively activate the closest environment (looking down, then up, withfindenv), optionally filtered by a list of<keywords>. Start looking in<basedir>(defaults to.).envie create[-2|-3|-e<pyexec>][-r<pip_req>][-p<pip_pkg>][-a][<envdir> |-t](aliasmkenv)Create virtual environment in<envdir>(or in a temporary dir,-t) based on a Python interpreter<pyexec>, optionally installing Pip requirements from<pip_req>file, and/or<pip_pkg>requirement specifier(s).envie remove(aliasrmenv)Destroy the active environment.envie list[-f|-l][<dir>] [<keywords>](aliaslsenv)List all environments below<dir>directory, optionally filtered with a list of<keywords>.envie find[-f|-l][<dir>] [<keywords>](aliasfindenv)Find the closest environments by first looking down and then dir-by-dir up the tree, starting in<dir>; optionally filtered with a list of<keywords>.envie <script>,envie python <script>Run Pythonscriptin the closest virtual environment.envie run <command>Execute arbitrarycommand/builtin/file/alias/functionin the closest virtual environment.envie-tmp<script>Create a new temporary (throw-away) virtual environment, install requirements specified inside the<script>file, run the<script>, and destroy the environment afterwards.envie configInteractively configure Envie.envie index(Re-)index virtual environments (for faster searches withlocate).envie helpPrint usage help. For details on a specific command use the-hswitch (likeenvie find-h, ormkenv-h).DocumentationDocumentation is hosted by ReadTheDocs, latest version being available atenvie.rtfd.io.