DEV Community

Anurag Pandey
Anurag Pandey

Posted on

Copy venv from one folder to another and still be able to use it?

If you have ever copied the python virtual environment folder from one location to another and faced problem using it, this article will help you understand how you can solve this problem.

Let us first create a folder, named example and then create a virtual environment and install flask using pip

$ mkdir example
$ cd example
$ python -m venv venv
$ source venv/bin/activate
$ pip install Flask
Enter fullscreen mode Exit fullscreen mode

Now you have a virtual env with flask installed.

After doing this python sets an environment variable VIRTUAL_ENV, let us check its value.

$ echo $VIRTUAL_ENV
/home/username/example/venv
Enter fullscreen mode Exit fullscreen mode

We will now move this venv folder to some other folder.

$ mkdir example2
$ mv venv/ example2/
$ cd example2
$ source venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

Now let us check the value of VIRTUAL_ENV variable

$ echo $VIRTUAL_ENV
/home/username/example/venv
Enter fullscreen mode Exit fullscreen mode

Wow, this is strange. I have moved the folder but still the value of VIRTUAL_ENV variable is the same?
This is because when you create the virtual environment, the location is hardcoded based on current directory.
You can check this inside activate file we have previously used to activate the virtual environment.
You will find something like VIRTUAL_ENV='/home/username/example/venv'.

The solution for using the virtual environment at the new location is simple. Just change this path in all program inside venv/bin directory to the new path :-)
Please don't do it manually!!!
Use tools like sed on unix or similar tools for the same.

Example using sed:

$ old_path='/home/username/example/venv'
$ new_path='/home/username/example/example2/venv'
$ cd venv/bin/
$ sed -i "s|$old_path|$new_path|g" *
Enter fullscreen mode Exit fullscreen mode

The last command is replace in-place the value of old_path with new_path. * signifies all files in current directory(not exactly, but for this example consider it). Make sure you run this command while present in venv/bin folder.

After doing this reactivate the virtual env.

$ source venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

And voila!

Reference:

  1. For sed command used: https://stackoverflow.com/questions/10309968/sed-search-and-replace-strings-containing

Top comments (5)

Collapse
 
ferdnyc profile image
Frank Dana

Continuing on the "don't do it manually!" advice, another thing you can do to make this process more streamlined is avoid writing the path variables manually.

If you've run the (unmodified) activation script, $old_path is just $VIRTUAL_ENV. And if you're in the moved venv/bin directory, $new_path is $(realpath ..) (Note: Won't work on stock macOS, which inexplicably does not ship with a realpath command.)

So the script could be reduced/simplified to...

cd venv/bin
source ./activate
sed -e "s|${VIRTUAL_ENV}|$(realpath ..)|g" *
Enter fullscreen mode Exit fullscreen mode
Collapse
 
stephenskett profile image
Stephen Skett

This is a really handy tip, thank you for sharing!

One slight issue which might be worth flagging though: using the sed command on a virtual env's bin folder will break any sym-links to e.g. the env's Python commands. So these will need to be recreated afterwards.

Collapse
 
ferdnyc profile image
Frank Dana

One slight issue which might be worth flagging though: using the sed command on a virtual env's bin folder will break any sym-links to e.g. the env's Python commands. So these will need to be recreated afterwards.

Yeah, like Maksim I'm not sure I really understand that warning.

If there are any symlinks TO anything in the $VENV/bin/ folder, and they're absolute symlinks, then yes they'll get broken — but it's moving the directory that will break them, not editing paths with sed.

Editing paths with sed is necessary to fix things inside the venv, after moving it. Primarily:

  1. The activation scripts, which as mentioned contain the full path to the directory in the VIRTUAL_ENV shell variable
  2. The shebang lines of any of the packages' entry_point scripts created in $VENV/bin, which will similarly contain the full path to the symlinked python3 executable inside that directory.

It's true that if there are any external symlinks (I can't fathom why there would be), moving the directory will break those as well, but sed has nothing to do with it, and you can't break any symlink by modifying a file's contents with sed.

Collapse
 
mzhumakhanov profile image
Maksim Zhumakhanov

Please could you provide any details for understanding? As I understand, when I replace a wrong old path with a proper new one, then all paths become correct and all files can be found by the new paths. How it could break symlinks?

Collapse
 
antonpetrov profile image
Anton Petrov

This as awesome!