17.03.2009
Сегодня писал для своих сотрудников мануал по созданию и поддержке окружения для разработки на Python. В нашем случае - сприцелом на Django, но мануал довольно обобщённый.
Ничего нового здесь нет и не предполагалось, просто описана методика совместного использования нескольких инструментов разного уровня для создания стабильной эко-системы, не подверженной колебанию настроения пользователя (кто активно использовал easy_install, тот поймёт о чём я). Пост, на первый взгляд, несколько в стороне от заявленной темы блога, но писалось с прицелом на пользователей Debian/Ubuntu и подходы использованные для решения задачи - очень в духе Debian. Любые конструктивные отзывы приветствуются.
Для того, чтобы приступить к разработке, нужно иметь некоторым образом настроенное окружение. Для настройки окружения есть три пути:
Первый вариант включает слишком много «но» и «если», а кроме того имеет тот недостаток, что не позволяет использовать для разных проектов разные версии библиотек. Тем не менее, он применяется на боевых серверах и имеет право на существование. Достоинства использования системных сборок библиотек - очевидны: стабильность, обновления, гарантированная поддержка.
Второй подход так же имеет сложности с инсталляцией различных версий библиотек одновременно, но имеет и то преимущество, что не вступает в конфликт с библиотеками, установленными через систему управления пакетами ОС.
Третий подход - наиболее гибкий, но частично конфликтует со вторым. Если в пользовательское окружение установлена библиотека одной версии, то в окружение проекта другую версию этой библиотеки добавить можно, но довольно нетривиально и будет скорее грязным хаком, чем решением.
Здесь предлагается использовать некоторую смесь всех трёх подходов, чтобы на выходе получить гибкое и масштабируемое окружение для разработки.
Из репозитариев нужно установить python-setuptools. Python устанавливается по умолчанию, версия зависит от версии ОС, на современных Debian(based) (Debian Lenny, Ubuntu >= 8.04) дистрибутивах это Python 2.5.
$ sudo aptitude install python-setuptools python-virtualenv ipython
Раньше я рекомендовал устанавливать переменную окружения PYTHONPATH
и создавать конфиг ~/.pydistutils.cfg
. Выяснилось, что идея хорошая, но только для идеальной сферической инсталляции. PYTHONPATH
из скриптов запуска нужно убрать. Конфиг прибить.
Дебиановский easyinstall по умолчанию устанавливает пакеты в /usr/lib/python2.5/site-packges
, что, наверное, здорово, но только если есть желание когда-нибудь воткнуться в конфликт с системным пакетным менеджером, поскольку об установке через easyinstall он ничего не знает и не должен. Чтобы решить эту проблему, создаём в домашней директории структуру папок:
~/.python/
bin/
lib/
В bin
будут устанавливаться исполнимые файлы (нужно добавить в PATH), в lib
- библиотеки (нужно рассказать системному питону, что по этому пути тоже нужно искать библиотеки и разворачивать .pth).
$ mkdir -p ~/.python/bin && mkdir ~/.python/lib
Редактируем файл, исполняющийся при запуске оболочки (варианты: ~/.profile
, ~/.bash_profile
, ~/.bashrc
). Нужно добавить вот такую конструкцию:
if [ -d ~/.python ]; then
export PATH="~/.python/bin:${PATH}"
fi
Редактируем /etc/python2.5/sitecustomize.py
(скорее всего, это специфичный для Debian скрипт, возможно в других ОС его нет). В него добавить следующее:
import os, site
site.addsitedir(os.path.expanduser('~/.python/lib'))
Если /etc/python2.5/sitecustomize.py
в не нашёлся, то, как альтернативное решение можно в любом из имеющихся sitedir’ов добавить файл userdir.pth
(название произвольное, лишь бы *.pth) следующего содержания:
import os, site; site.addsitedir(os.path.expanduser('~/.python/lib'))
Теперь пакеты можно устанавливать easy_install’ом в домашнюю папку:
$ easy_install -d ~/.python/lib -s ~/.python/bin pip ipdb
Для удобства в .bashrc
можно создать альяс:
alias e-i='easy_install -d ~/.python/lib -s ~/.python/bin'
Окружение будет управляться [http://pypi.python.org/pypi/virtualenv утилитой создания виртуальных окружений virtualenv] и [http://pip.openplans.org/ менеджером пакетов pip]. Про pip имеет смысл написать чем он лучше/хуже привычного easy_install. Лучше тем, что умеет устанавливать версии программных пакетов из всех популярных VCS (по состоянию на 0.3.1 поддерживаются subversion, git, mercurial и bazaar). Ещё умеет устанавливать набор пакетов по списку и умеет этот же список генерировать из окружения. Хуже - тем, что скомпилированные пакеты ставить не умеет, для установки бинарных библиотек потребуется доступ к исходникам, наличие компилятора и скорее всего заголовки python (sudo aptitude install build-essential python-dev
).
Последовательность действий такая:
Как-то так:
$ svn co https://example.org/svn/example-project/trunk ./examlple-project
Используемая VCS здесь не принципиальна, это может быть и Git и вообще что угодно. Можно вообще VCS не использовать (как?!!! как можно жить без VCS?!!!). На выходе нужно просто получить рабочую копию.
$ virtualenv ./example-project
Разработчикам следует обратить внимание, что virtualenv
создаёт в рабочей копии некоторую структуру папок, которую нужно исключить из контроля версий, потому, что её содержимое может оказаться специфичным для локальной системы, а воспроизвести его в другом месте - не проблема.
$ cd ./example-project
$ source ./bin/activate
Это нужно будет проделывать каждый раз, чтобы достучаться до окружения проекта. Запомнить или вытатуировать на указательном пальце.
Первый вариант: разработчик предусмотрел использование pip для проекта и создал файл с требованиями (молодец!). В этом случае действуем так:
$ pip install -E ./ -I -r reqs.txt
reqs.txt
- файл с требованиями. Подробности в [http://pip.openplans.org/#requirements-files документации pip].
Второй вариант: разработчик ничего такого не предусмотрел (как обычно), но нам известно, что проект требует наличия пиноновской библиотеки markdown в версии 1.7 и Django последней версии:
$ pip install -E ./ -I markdown==1.7 django
Если поставили что-то лишнее или вообще окружение сломали (можно, я умею), то можно его (окружение) зачистить:
$ rm -r ./bin && virtualenv --clear ./
В заключении хотел написать о том как это всё круто и правильно, но сил уже не осталось. Тем более, что всё это не очень-то круто и не совсем правильно, а скорее от безысходности. Веб-разработчику часто приходится использовать чужой код, который стабилен в одной ревизии и кишит багами уже в следующей. Неидеальный мир, в котором всё устроено не по-хемульски.
17.03.09 20:29 Ignatov комментирует:
За написание удобных и прозрачны команд разработчики скажут спасибо.
Потом просто пишем make clean && make sandbox и make собирает нам новую песочницу.
17.03.09 20:48 Alexander комментирует:
17.03.09 21:06 uptimebox комментирует:
Спасибо, изучу.
LEXX:
Есть скрипты развёртывания и обновления на базе Fabric (http://www.nongnu.org/fab/), но к публикации они абсолютно не готовы. Слишком специфичны для конкретного коллектива.
19.03.09 21:22 Mikhail комментирует:
24.03.09 17:48 kamedov комментирует:
кстати собрать нужное окружение с необходимым пакетом библиотек можно одной командой:
pip install -E название-окружения -r файл-с-версиями-пакетов –src=/путь/к/папке/с/кэшем/репозиториев/
последняя опция сильно ускоряет процесс сборки, если уже есть копии репозиториев с нужными версиями библиотек
29.06.09 10:53 Evgeny Ratnikov комментирует:
в ~/.bashrc
export PYTHONUSERBASE=$HOME/python-dev/
в ~/.pydistutils.cfg
[install]
user=True
15.07.11 08:56 www.google.com комментирует:
mkdir -p ~/.python/{bin,lib}