Протестировать свежую версию любимого фреймоврка. Запустить приложение со специфичным набором библиотек. Установить необходимые библиотеки по списку зависимостей. Как решить все эти задачи не затронув системные файлы? В этой статье речь пойдет об утилитах virutalenv и pip.
Утилита vitrualenv предназначена для создания изолированных окружений Python. Под окружением понимается собственно интерпретатор и набор библиотек к нему. Утилита pip органично дополняет easy_install, делая установку пакетов еще проще. Подробную информацию о всех полезностях, которые virutalenv и pip дают разработчику, вы сможете узнать, посетив странички pypi.python.org/pypi/virtualenv и pypi.python.org/pypi/pip. Я же покажу на примере как все это можно использовать для экспериментов с проектами на языке Python.
Суть данного проекта предельно проста. Эта небольшая консольная программулька с именем hl.py будет раскрашивать исходный код скриптов для вставки в хабратопик. Через командую строку она принимает путь к файлу с исходником и язык, а в ответ печатает нужный html код. Например, вот так она раскрашивает сама себя:
Упс, не работает. Сообщение говорит о том, что не установлен дистрибутив lxml версии 2.2.2. Посмотрим, что есть в Ubuntu:
Действительно есть что-то похожее, но, определенно, не той версии которая требует эта программулька. А как узнать, что такое lxml? Воспользуемся утилитой yolk (http://pypi.python.org/pypi/yolk).
Почему разработчики Ubuntu не сделали пакет для такой полезной утилитки?…
Однако, это не проблема. У нас есть возможность сделать собственное окружение Python, не зависящее от причуд создателей дистрибутива операционной системы. Сохраните на диск следующий скрипт под именем vipsetup и сделайте его исполняемым:
Создайте новое изолированное окружение, при помощи команд:
А теперь установите yolk, используя команду pip:
Вот и описание. Установите lxml требуемой версии:
Теперь, все готово для запуска нашей программульки:
Вот она, вся такая цветная. Наслаждайтесь. :) И запишите где-нибудь список зависимостей, на память:
Если потребуется, быстренько восстановите при помощи команды:
зы: если практическая полезность данного эксперимента вам показалось сомнительной, сделайте:
Утилита vitrualenv предназначена для создания изолированных окружений Python. Под окружением понимается собственно интерпретатор и набор библиотек к нему. Утилита pip органично дополняет easy_install, делая установку пакетов еще проще. Подробную информацию о всех полезностях, которые virutalenv и pip дают разработчику, вы сможете узнать, посетив странички pypi.python.org/pypi/virtualenv и pypi.python.org/pypi/pip. Я же покажу на примере как все это можно использовать для экспериментов с проектами на языке Python.
Суть данного проекта предельно проста. Эта небольшая консольная программулька с именем hl.py будет раскрашивать исходный код скриптов для вставки в хабратопик. Через командую строку она принимает путь к файлу с исходником и язык, а в ответ печатает нужный html код. Например, вот так она раскрашивает сама себя:
$ ./ht.py ./hl.py python
Traceback (most recent call last):
File "./hl.py", line 3, in <module>
pkg_resources.require('lxml==2.2.2')
File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 626, in require
needed = self.resolve(parse_requirements(requirements))
File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 524, in resolve
raise DistributionNotFound(req) # XXX put more info here
pkg_resources.DistributionNotFound: lxml==2.2.2
Упс, не работает. Сообщение говорит о том, что не установлен дистрибутив lxml версии 2.2.2. Посмотрим, что есть в Ubuntu:
$ apt-cache show python-lxml | grep -E ^Version
Version: 2.1.5-1ubuntu2
Действительно есть что-то похожее, но, определенно, не той версии которая требует эта программулька. А как узнать, что такое lxml? Воспользуемся утилитой yolk (http://pypi.python.org/pypi/yolk).
$ yolk -f summary -M lxml
bash: yolk: команда не найдена
$ apt-cache search yolk
$
Почему разработчики Ubuntu не сделали пакет для такой полезной утилитки?…
Однако, это не проблема. У нас есть возможность сделать собственное окружение Python, не зависящее от причуд создателей дистрибутива операционной системы. Сохраните на диск следующий скрипт под именем vipsetup и сделайте его исполняемым:
#!/bin/sh
# Setup virtual environment for python and pip
# Usage:
# vipsetup [directory]
ENV_DIR="$1"
VIRTUALENV_BIN='virtualenv'
VIRTUALENV_ARGS='--no-site-packages'
if [ ! -f $ENV_DIR/bin/activate ]; then
if ! type "$VIRTUALENV_BIN"; then
if ! type "easy_install"; then
echo "Error: easy_install executable not found."
echo "To install easy_install type:"
echo " sudo apt-get install python-setuptools"
exit 1
fi
TMPDIR=`mktemp -d -t ve.XXXXXXXXXX` || exit 1
PYTHONPATH=$TMPDIR easy_install --install-dir=$TMPDIR virtualenv || exit 1
PYTHONPATH=$TMPDIR $TMPDIR/virtualenv "$@" $VIRTUALENV_ARGS || exit 1
rm -rf $TMPDIR
else
$VIRTUALENV_BIN "$@" $VIRTUALENV_ARGS || exit 1
fi
fi
if [ ! -e $ENV_DIR/bin/pip ]; then
$ENV_DIR/bin/easy_install pip || exit 1
fi
echo ""
echo "Installation complete"
echo "* To activate virtual environment type:"
echo " . $ENV_DIR/bin/activate"
echo "* To install python package type:"
echo " $ENV_DIR/bin/pip install <package>"
if [ -z "$PIP_DOWNLOAD_CACHE" ]; then
echo "* To enable cache for downloads"
echo " set environment variable PIP_DOWNLOAD_CACHE with a path"
fi
Создайте новое изолированное окружение, при помощи команд:
$ mkdir -p /tmp/testenv
$ cd /tmp/testenv
$ vipsetup .
$ . /bin/activate
(testenv) $
А теперь установите yolk, используя команду pip:
(testenv) $ pip install yolk
...
(testenv) $ yolk -f summary -M lxml
summary: Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.
Вот и описание. Установите lxml требуемой версии:
(testenv) $ pip install lxml==2.2.2
Теперь, все готово для запуска нашей программульки:
(testenv) $ ./hl.py ./hl.py python
#!/usr/bin/env python<br>import pkg_resources<br>
pkg_resources.require('lxml==2.2.2')<br>
<br>from lxml.html import parse, submit_form, tostring<br>
<br>def highlight(code, language):<br>
SERVICE = 'http://highlight.hohli.com/'<br>
doc = parse(SERVICE)<br>
form = doc.getroot().forms[0 ]<br>
form.fields['language'] = language<br>
form.fields['use_font'] = 1 # for habrahabr<br>
form.fields['code'] = code<br>
form.action = form.action or form.base_url # hack<br>
ans = parse(submit_form(form))<br>
highlited = ans.getroot().cssselect('.source .src')[0 ]<br>
return ''.join([tostring(x) for x in highlited]<br>
).replace('0</font>', '0 </font>' # fix habrahabr <br>
).replace('blockquote>', 'code>') # fix format <br>
<br>if __name__ == "__main__":<br>
import sys<br>
def main(*args, **kwargs):<br>
fh = sys.stdin if args[0 ] == '-' else file(args[0 ])<br>
language = args[1]<br>
code = unicode(fh.read())<br>
print highlight(code, language)<br>
return 0 <br>
sys.exit(main(*sys.argv[1:]))<br>
Вот она, вся такая цветная. Наслаждайтесь. :) И запишите где-нибудь список зависимостей, на память:
(testenv) $ pip freeze | tee requirements.txt<br>
lxml==2.2.2
wsgiref==0.1.2
yolk==0.4.1
Если потребуется, быстренько восстановите при помощи команды:
(testenv) $ pip install -r requirements.txt
зы: если практическая полезность данного эксперимента вам показалось сомнительной, сделайте:
(testenv) $ deactivate
$ rm -rf /tmp/testenv
и будем считать, что ничего не было. ;)