Skip to content

Run things from outside the venv

Let's create a small script in our project, which requires the venv to succeed:

% print -rl '#!/usr/bin/env python3' 'import bs4' 'print("SUCCESS")' >do_thing.py
% chmod +x do_thing.py

We can ensure we've got a proper environment and run it:

% envin
[venv] % ./do_thing.py

Animated demo: envin, run script

But what if we don't want to manually activate its environment?

[venv] % envout
% ./do_thing.py
Traceback (most recent call last):
  File "~/newproj/do_thing.py", line 2, in <module>
    import bs4
ModuleNotFoundError: No module named 'bs4'

vpy

% vpy do_thing.py
SUCCESS

By default, vpy does not activate the script's folder's venv; it just uses that venv's Python. This is usually good enough, and faster, than activating.

If it's not enough, you can pass --activate.

Either way, the current shell is unaffected.

For something similar and more flexible, see vrun below.

vpyshebang

% vpyshebang do_thing.py
% cat do_thing.py
#!/home/andy/.local/share/venvs/3f6372258375d0a2f18efd20d84fc2b5/venv/bin/python
#!/usr/bin/env python3
import bs4
print("SUCCESS")

The full path to the venv's interpreter has been prepended to the script in shebang form, so that it can be successfully called from anywhere.

If you find that unsightly, inflexible, or would just like vpy available outside of Zsh, create a "standalone" vpy script:

% zpy mkbin vpy ~/.local/bin

Next time you use vpyshebang, it will use the path to that script, instead.

vrun

The minimal form of vrun is

% vrun <proj-dir> <cmd>...

The command passed will be run in a subshell whose PATH is prepended with <proj-dir>'s associated <venv>/bin.

% vrun .. which python

This is much faster than activating and usually sufficient, but you can pass --activate when you need to.

Passing --cd will run the command from within the project folder.

The current shell will remain unaffected.

vlauncher

You can use vlauncher to generate a small POSIX launcher script, for running a command in a given project's activated venv:

% vlauncher ~/newproj 'which python' start.sh
% cat start.sh
#!/bin/sh -e
. /home/andy/.local/share/venvs/3f6372258375d0a2f18efd20d84fc2b5/venv/bin/activate
exec which python $@

If you pass --link-only, it will instead just create a symlink to <venv>/bin/<cmd>, which should already have the venv's python in its shebang line.

Editor Settings

vpysublp will specify the venv interpreter associated with the current folder in a new or existing Sublime Text project file.

vpypyright does the same in a new or existing Pyright settings file, and vpyvscode in a new or existing [VS]Code settings file.