开发者

How to duplicate virtualenv

I have an existing virtualenv with a lot of packages but an old version of Django.

What I want to do is duplicate this environment so I have another environment with the exa开发者_运维技巧ct same packages but a newer version of Django. How can I do this?


The easiest way is to use pip to generate a requirements file. A requirements file is basically a file that contains a list of all the python packages you want to install (or have already installed in case of file generated by pip), and what versions they're at.

To generate a requirements file, go into your original virtualenv, and run:

pip freeze > requirements.txt

This will generate the requirements.txt file for you. If you open that file up in your favorite text editor, you'll see something like:

Django==1.3
Fabric==1.0.1
etc...

Now, edit the line that says Django==x.x to say Django==1.3 (or whatever version you want to install in your new virtualenv).

Lastly, activate your new virtualenv, and run:

pip install -r requirements.txt

And pip will automatically download and install all the python modules listed in your requirements.txt file, at whatever versions you specified!


Another option is to use virtualenv-clone package:

A script for cloning a non-relocatable virtualenv.


virtualenvwrapper provides a command to duplicate virtualenv

cpvirtualenv ENVNAME [TARGETENVNAME]


Easiest option is using virtualenv-clone package.

To duplicate venv1 to venv2, follow these steps:

  1. Install virtualenv-clone in either venv1 or a dummy virtual environment venv_dummy. To create venv_dummy:

    python -m virtualenv venv_dummy
    source venv_dummy/bin/activate
    
  2. To install virtualenv-clone:

    (venv_dummy): pip install virtualenv-clone
    
  3. To duplicate venv1 to venv2:

    (venv_dummy): virtualenv-clone venv1/ venv2/
    


If you are using Anaconda you can just run:

conda create --name myclone --clone myenv

This will copy myenv to the newly created environment called myclone.


Here is my go to command for cloning python virtual environments.

packs=`source-path/bin/pip freeze` && python3 -m venv <env-name> && target-path/bin/pip install $packs

Conventions used in above command:

  • source-path = path to env that you want to clone e.g. /home/john/envs/oldenv.
  • env-name = name of the cloned env e.g. myenv, it can be a path as well e.g. /home/john/envs/myenv
  • target-path = path to new cloned env e.g. /home/john/envs/<env-name>

Advantages of using this or why i prefer this

  1. No need to generate a requirements.txt file.
  2. No environment is activated/deactivated during cloning process.
  3. single command to be executed(3 commands ran at once).

In some cases you might want to exclude global packages from while cloning env you can replace source-path/bin/pip freeze with source-path/bin/pip freeze --local, more about --local here


In case you use pip "venv". I copy pasted the folder holding the virtual environment and manually changed the files in the bin folder of the copied folder. I don't know if its efficient,but it works!


Can you not simply:

  • Copy the existing virtual env directory to a new one
  • Update to the new Django?


pip works, but it's a problem on a computer without internet.

I wrote a small code for this, it worked for me. I'm writing it here because maybe it will be useful for someone else.

( Note: I tested it on Windows )

  1. copy project folder
  2. paste project folder to another directory
  3. change the address parts in this code and run the code:
import os

# The new address of our script folder
script_folder = r'D:\Python proqrams\pdf_to_excel\venv\Scripts'

# the old address of our venv folder
old_path = rb'C:\Users\AVG-dell\Desktop\pdf_to_excel\venv'

# the new address of our venv folder
new_path = rb"D:\Python proqrams\pdf_to_excel\venv"


def find_replace( folder ):

    names = os.listdir( folder )

    for name in names:
        current_path = os.path.join( folder, name )

        if os.path.isdir( current_path ):
            find_replace( current_path )

        elif os.path.isfile( current_path ) :

            try:
                with open( current_path ,'rb' ) as f:
                    data = f.read()

                if old_path in data:
                    print( current_path )

                    data2 = data.replace( old_path , new_path )

                    with open( current_path , 'wb' ) as f:
                        f.write(data2)


            except:
                pass



find_replace( script_folder )

print('completed')
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜