I mentioned in my previous post that I borked my system meddling with Python. Having reset my workspace, I’ve now set up a solid system that makes handling projects and multiple development environments super simple.
The new set up easily handles multiple Python projects, without compatibility or version conflicts. The installation is equally straightforward.
Before switching to a desktop Linux, I used to sing the praises of VMware and developing with virtual machines when dealing with unique environments. By “unique”, I rather mean any odd project out of the ordinary LAMP set-up I usually work with, or something that requires a specific version of a piece of software.
Since then however, I’ve found no need. So long as you think before you leap.
Virtual boxes (as closed, single-piece software) are good and all, you can be as venturous as you wish without risk of damaging your native system. Plus, if you screw one of these you can restore a saved state in a few clicks. However, the VM safety net allows you to proceed without caution, perhaps recklessly, at the expense of fully comprehending the commands you’re executing and tasks you’re running.
In that sense, they’re great for beginners uncertain of how (or if) they should install software, e.g. Apache, PHP, Python etc — appliances and virtual stacks are helpful.
Otherwise they can convolute your workspace — and more often than not, won’t be configured exactly how you want or need them. Running software natively is simple and as intended, it also allows you to configure your entire environment without any assumptions made by distributors.
Virtualenv is quite the revelation. It facilitates multiple isolated Python environments on a single system, dynamically handling your Python Path so packages are install within an enclosed local directory, rather than in amongst your top-level system packages.
This means you can create project-by-project virtual environments avoiding compatibility and version conflicts. When an environment is created (and activated) libraries are thereafter installed within discreet directories that aren’t shared with other virtualenv environments.
This means nothing is installed “system-wide”, so libraries don’t accrue over time, there’s no balancing of versions. It also means you can work with different version of Python simultaneously.
Python packages should be installed with a package manager. The latest of which is pip.
Prior to this, easy_install was the manager du jour (part of Setuptools, both now out-dated), but we’ll only be using that to install pip:
$ sudo easy_install pip
Pip is a direct replacement for easy_install, improving on a few things (a comparison can be found on the installer site). Packages that are available with easy_install should be pip-installable and the installation method is the same — the following installs virtualenv:
$ sudo pip install virtualenv
With virtualenv installed we can create an environment within your workspace, all it needs is the environment directory name, here ‘env’:
$ virtualenv env
There are a few options you have with this command. In the following example, the
--no-site-packages flag means that the new environment will not inherit any system-wide global site packages. The
--distribute flag will install Distribute rather than Setuptools:
$ virtualenv --no-site-packages --distribute env
Anyway, activate your environment:
$ source env/bin/activate
You’ll see from your shell prompt that the environment is activated, with the name prepended.
Then we’ll install something with pip. Yolk is a tool for querying the packages currently installed on your system, so we’ll install that and grab a list:
(env) $ pip install yolk
(env) $ yolk -l
Then you’ll see everything the environment can see in the output (this will depend on your global site packages and how you created the environment, as above).
Note that you don’t need to sudo whilst in the activated environment.
As a test, we’ll
deactivate the environment and run the same command, which gets the following error (unless you have yolk installed globally):
(env) $ deactivate
$ yolk -l
yolk: command not found
If installed within an environment, a package is only available whilst it is activated. This is the means to install whatever you wish, without worrying about cross-project conflicts.
Another good feature of pip is to generate a list of requirements for your working set of packages. The command is called freeze and generates a text file as follows:
(env) $ pip freeze > requirements.txt
This will create a list of all installed packages with specific versions for each library. This is in a custom syntax and looks something like this:
This list can then be distributed (e.g. to a team of developers) and used to install those packages on other systems, like so:
(env) $ pip install -r requirements.txt
Note, this isn’t couple with virtualenv, which actually has it’s own method of bootstrapping — see “Creating Your Own Bootstrap Scripts”.