17.03.2009

Настройка окружения разработки на Python

Сегодня писал для своих сотрудников мануал по созданию и поддержке окружения для разработки на Python. В нашем случае - сприцелом на Django, но мануал довольно обобщённый.

Ничего нового здесь нет и не предполагалось, просто описана методика совместного использования нескольких инструментов разного уровня для создания стабильной эко-системы, не подверженной колебанию настроения пользователя (кто активно использовал easy_install, тот поймёт о чём я). Пост, на первый взгляд, несколько в стороне от заявленной темы блога, но писалось с прицелом на пользователей Debian/Ubuntu и подходы использованные для решения задачи - очень в духе Debian. Любые конструктивные отзывы приветствуются.

Введение

Для того, чтобы приступить к разработке, нужно иметь некоторым образом настроенное окружение. Для настройки окружения есть три пути:

  1. Настройка системного окружения
  2. Настройка пользовательского окружения
  3. Настройка окружения проекта

Первый вариант включает слишком много «но» и «если», а кроме того имеет тот недостаток, что не позволяет использовать для разных проектов разные версии библиотек. Тем не менее, он применяется на боевых серверах и имеет право на существование. Достоинства использования системных сборок библиотек - очевидны: стабильность, обновления, гарантированная поддержка.

Второй подход так же имеет сложности с инсталляцией различных версий библиотек одновременно, но имеет и то преимущество, что не вступает в конфликт с библиотеками, установленными через систему управления пакетами ОС.

Третий подход - наиболее гибкий, но частично конфликтует со вторым. Если в пользовательское окружение установлена библиотека одной версии, то в окружение проекта другую версию этой библиотеки добавить можно, но довольно нетривиально и будет скорее грязным хаком, чем решением.

Здесь предлагается использовать некоторую смесь всех трёх подходов, чтобы на выходе получить гибкое и масштабируемое окружение для разработки.

  1. На системном уровне устанавливаются сам Python и библиотеки, уже попавшие в стабильную ветку Debian;
  2. На уровне пользователя устанавливаются библиотеки, нужные для процесса разработки в целом, но недоступные в стабильном репозитарии, или имеющие в нём слишком старые версии;
  3. На уровне проекта устанавливаются библиотеки, которые доступны только из репозитариев, а так же библиотеки, необходимые версии которых могут измениться в будущем.

Подход 1. Системное окружение

Из репозитариев нужно установить python-setuptools. Python устанавливается по умолчанию, версия зависит от версии ОС, на современных Debian(based) (Debian Lenny, Ubuntu >= 8.04) дистрибутивах это Python 2.5.

$ sudo aptitude install python-setuptools python-virtualenv ipython

Часть 2. Окружение домашнего каталога пользователя

Раньше я рекомендовал устанавливать переменную окружения 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'

Часть 3. Окружение проекта

Окружение будет управляться [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).

Последовательность действий такая:

3.1 Извлечение проекта из репозитария

Как-то так:

$ svn co https://example.org/svn/example-project/trunk ./examlple-project

Используемая VCS здесь не принципиальна, это может быть и Git и вообще что угодно. Можно вообще VCS не использовать (как?!!! как можно жить без VCS?!!!). На выходе нужно просто получить рабочую копию.

3.2 создание виртуального окружения

$ virtualenv ./example-project

Разработчикам следует обратить внимание, что virtualenv создаёт в рабочей копии некоторую структуру папок, которую нужно исключить из контроля версий, потому, что её содержимое может оказаться специфичным для локальной системы, а воспроизвести его в другом месте - не проблема.

3.3 переключение в окружение проекта

$ cd ./example-project
$ source ./bin/activate

Это нужно будет проделывать каждый раз, чтобы достучаться до окружения проекта. Запомнить или вытатуировать на указательном пальце.

3.4 установка необходимых библиотек

Первый вариант: разработчик предусмотрел использование 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 комментирует:

Ignatov:

Спасибо, изучу.

LEXX:

Есть скрипты развёртывания и обновления на базе Fabric (http://www.nongnu.org/fab/), но к публикации они абсолютно не готовы. Слишком специфичны для конкретного коллектива.

19.03.09 21:22 Mikhail комментирует:

Неплохой мануал, правда смотрел только на команды. Зря назвал документ для дебианщиков, потому что так же поступают питонисты под всеми операционными системами

24.03.09 17:48 kamedov комментирует:

+1 предыдущему коментатору - использую pip под виндой. с ним очень удобно контролировать версии пакетов.

кстати собрать нужное окружение с необходимым пакетом библиотек можно одной командой:

pip install -E название-окружения -r файл-с-версиями-пакетов –src=/путь/к/папке/с/кэшем/репозиториев/

последняя опция сильно ускоряет процесс сборки, если уже есть копии репозиториев с нужными версиями библиотек

29.06.09 10:53 Evgeny Ratnikov комментирует:

с версии 2.6 поддерживается следующая конфигурацияЖ

в ~/.bashrc
export PYTHONUSERBASE=$HOME/python-dev/

в ~/.pydistutils.cfg
[install]
user=True

15.07.11 08:56 www.google.com комментирует:

mkdir -p ~/.python/{bin,lib}