Again, these are some very rough notes on using virtualenv, a work in progress...
virtualenv
virtualenv is a tool to create isolated Python environments. It is an extension of virtual-python.
Originally written by Ian Bicking, and sponsored by the Open Planning Project. It is licensed under an MIT-style permissive license.
Why use virtualenv
Virtualenv allows you to run multiple applications with different dependencies. For example if one application requires version 1 of LibFoo and another application requires version 2 you can create two virtualenv for each application and they can live happily on the same system.
This also works for virtual hosts when you can not install to the global site-packages directory.
Each environment created using virtualenv has its own installation directories that do not share libraries with other virtualenv environments (and optionally do not use the globally installed Python libraries either).
virtualenv can be used to create an isolated Python environment for you that does not have access to packages installed system-wide.
Important Notes
virtualenv probably needs to be customized for your source and target environments. While it can be used to created an awesome deployment system, your configuration can vary a lot depending on your source and target systems. So before you start typing up a custom installer you will want to fully research the many different parameters.
Key Factors:
- You will want to read a lot of stuff before proceeding.
- This will take a lot of time.
- Do prefer setuptools or distribute
- Is one of your systems a virtual host ?
- Are you running mod_python or mod_wsgi ?
- Are you prepared to learn about virtualenv, pip, fabric and any other required tools and/or helpers?
- A posix / unix / linux / os x system will be significantly easier to setup up fro deployment.
Installation
easy_install
You can install it with easy_install virtualenv, or from the hg repository or from a tarball easy_install virtualenv==tip.
resources
http://pypi.python.org/pypi/virtualenv#creating-your-own-bootstrap-scripts
Usage
Basics
A basic setup creates ENV/lib/python2.4/site-packages
(or ENV/lib/python2.5/site-packages
on Python 2.5) where any libraries you install can go. It also creates ENV/bin/python, which is a Python interpreter that uses the custom environment. Anytime you use that interpreter (including when a script has #!/path/to/ENV/bin/python in it) the libraries in that environment will be used.
Windows scripts and executables on Windows go in ENV\Scripts\
; everywhere you see bin/
replace it with Scripts\
In addition, by default, Setuptools is installed for you, and if you use ENV/bin/easy_install
the packages will be installed into the environment.
ENV=my_custom_environment
python virtualenv.py ENV
Using distribute rather than setuptools
You can create a virtualenv that uses distribute rather than the default setuptools If you use the --distribute option, it will install distribute for you, instead of setuptools, and if you use ENV/bin/easy_install` the packages will be installed into the environment.
To use Distribute instead of setuptools, just call virtualenv like this:
python virtualenv.py --distribute ENV
- You can also set the environment variable VIRTUALENV_USE_DISTRIBUTE (since 1.4.4) and be a good Comrade
No site packages option
If you build with virtualenv --no-site-packages ENV it will not inherit any packages from /usr/lib/python2.5/site-packages (or wherever your global site-packages directory is). This can be used if you don't have control over site-packages and don't want to depend on the packages there, or you just want more isolation from the global system.
virtualenv --no-site-packages ENV
Using Virtualenv without bin/python
Sometimes you can't or don't want to use the Python interpreter created by the virtualenv. For instance, in a mod_python or mod_wsgi environment, there is only one interpreter.
Luckily, it's easy. You use the custom Python interpreter to install libraries. To use your libraries, you just have to be sure the path is correct. A script is available to correct the path. You can setup the environment like:
activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
This will change sys.path and even change sys.prefix, but also allow you to use an existing interpreter. Items in your environment will show up first on sys.path, before global items. However, this cannot undo the activation of other environments, or modules that have been imported. You shouldn't try to, for instance, activate an environment before a web request; you should activate one environment as early as possible, and not do it again in that process.
modwsgi
Reference
http://code.google.com/p/modwsgi/wiki/VirtualEnvironments
To create a virgin environment using the 'virtualenv' program, the '--no-site-packages' option should be used.
cd /usr/local/pythonenv
virtualenv --no-site-packages ENV
Example output:
New python executable in ENV/bin/python
Installing setuptools............done.
Important Note: The version of Python from which this baseline environment is created must be the same version of Python that mod_wsgi was compiled for. It is not possible to mix environments based on different major/minor versions of Python.
Once the baseline Python environment has been created, the WSGIPythonHome directive should be defined within the global part of the main Apache configuration files. The directive should refer to the top level directory for the baseline environment created by the 'virtualenv' script.
WSGIPythonHome /usr/local/pythonenv/BASELINE
This Python environment will now be used as the baseline environment for all WSGI applications running under mod_wsgi, whether they be run in embedded mode or daemon mode.
There is no need to set the WSGIPythonHome directive if you want to use the main Python installation as the baseline environment.
Note that the WSGIPythonHome directive can only be used on UNIX systems and is not available on Windows systems. This is because on Windows systems the location of the Python DLL seems to be what dictates where Python will look for the Python library files. It is not known at this point how one could create a distinct baseline environment independent of the main Python installation on Windows.
Activating your virtualenv
activate the virtual environment with:
~/$ cd ENV
~/ENV/$ source bin/activate
(ENV)~/ENV/$
Creating Your Own Bootstrap Scripts
You can create a bootstrap script that will sets up a customized environment for you using a bootstrapscript
using virtualenv.create_bootstrap_script(extra_text)
virtualenv.create_bootstrap_script(extra_text) creates the standard virtualenv.py script but includes your extra text (Python code)
virtualenv.create_bootstrap_script(extra_text)
If you include these functions, they will be called:
extend_parser(optparse_parser):
You can add or remove options from the parser here.
adjust_options(options, args):
You can change options here, or change the args (if you accept different kinds of arguments, be sure you modify args so it is only [DEST_DIR]).
after_install(options, home_dir) example:
After everything is installed, this function is called. This is probably the function you are most likely to use.
This example immediately installs a package, and runs a setup script from that package:
def after_install(options, home_dir):
if sys.platform == 'win32':
bin = 'Scripts'
else:
bin = 'bin'
subprocess.call([join(home_dir, bin, 'easy_install'),
'MyPackage'])
subprocess.call([join(home_dir, bin, 'my-package-script'),
'setup', home_dir])
Bootstrap Example
Here's a more concrete example of how you could use this:
import virtualenv, textwrap
output = virtualenv.create_bootstrap_script(textwrap.dedent("""
import os, subprocess
def after_install(options, home_dir):
etc = join(home_dir, 'etc')
if not os.path.exists(etc):
os.makedirs(etc)
subprocess.call([join(home_dir, 'bin', 'easy_install'),
'BlogApplication'])
subprocess.call([join(home_dir, 'bin', 'paster'),
'make-config', 'BlogApplication',
join(etc, 'blog.ini')])
subprocess.call([join(home_dir, 'bin', 'paster'),
'setup-app', join(etc, 'blog.ini')])
"""))
f = open('blog-bootstrap.py', 'w').write(output)
to be continued.
Comments (1)
0
chrismay77 14 years ago