Как развернуть приложение Python с библиотеками в качестве источника без каких-либо дополнительных зависимостей?
Фон. У меня есть небольшое приложение Python, которое облегчает жизнь разработчикам, выпускающим программное обеспечение в нашей компании. Я создаю исполняемый файл для Windows с помощью py2exe. Приложение, а также двоичные файлы проверяются в Subversion. Распространение происходит от людей, просто проверяющих каталог из SVN. Программа имеет около 6 различных зависимостей библиотеки Python (например, ElementTree, Mako)
Ситуация. Разработчики хотят взломать источник этого инструмента, а затем запустить его, не создавая двоичный файл. В настоящее время это означает, что им нужен интерпретатор python 2.6 (это хорошо), а также 6 локально установленных библиотек с помощью easy_install.
Проблема
- Это не общедоступная классическая среда с открытым исходным кодом: я внутри корпоративной сети, инструмент никогда не покинет "огороженный сад", и у нас есть серьезные неудобные препятствия для доступа к внешнему интернету (NTLM аутентифицирует прокси и/или машины без прямого доступа в Интернет).
- Я хочу, чтобы препятствия начали взламывать этот инструмент, чтобы быть минимальным: никто не должен был искать правильную зависимость в правильной версии, они должны выполнить как можно меньше настроек. Оптимально предпосылки были бы иметь установку Python и просто проверять программу из Subversion.
Анекдот: чем более самодостаточным, тем легче повторять его. У меня была моя машина, замененная на новую и прошла неприятный процесс, чтобы перепроектировать зависимости, переустановить distutils, обыскать библиотеки в Интернете и установить их для установки (см. Ограничения на корпоративный интернет).
Ответы
Ответ 1
Я иногда использую описанный ниже подход по той же причине, что и @Boris: я бы предпочел, чтобы использование некоторого кода было так же просто, как a) svn checkout/update - b) go.
Но для записи:
- Я использую virtualenv/easy_install большую часть времени.
- Я согласен в определенной степени с критиками @Ali A и @S.Lott
Во всяком случае, подход, который я использую, зависит от модификации sys.path и работает следующим образом:
- Требовать python и setuptools (чтобы включить загрузку кода из яиц) на всех компьютерах, которые будут использовать ваше программное обеспечение.
- Организуйте структуру своего каталога следующим образом:
project/
*.py
scriptcustomize.py
file.pth
thirdparty/
eggs/
mako-vNNN.egg
... .egg
code/
elementtree\
*.py
...
- На верхнем уровне script введите следующий код вверху:
from scriptcustomize import apply_pth_files
apply_pth_files(__file__)
- Добавьте файл scriptcustomize.py в папку проекта:
import os
from glob import glob
import fileinput
import sys
def apply_pth_files(scriptfilename, at_beginning=False):
"""At the top of your script:
from scriptcustomize import apply_pth_files
apply_pth_files(__file__)
"""
directory = os.path.dirname(scriptfilename)
files = glob(os.path.join(directory, '*.pth'))
if not files:
return
for line in fileinput.input(files):
line = line.strip()
if line and line[0] != '#':
path = os.path.join(directory, line)
if at_beginning:
sys.path.insert(0, path)
else:
sys.path.append(path)
- Добавьте один или несколько файлов *.pth в папку проекта. В каждой строке поместите ссылку на каталог с пакетами. Например:
# contents of *.pth file
thirdparty/code
thirdparty/eggs/mako-vNNN.egg
- Я "вроде", как этот подход. Что мне нравится: это похоже на то, как работают файлы *.pth, но для отдельных программ, а не для всех ваших пакетов сайтов. Что мне не нравится: нужно добавить две строки в начале сценариев верхнего уровня.
- Опять же: я использую virtualenv большую часть времени. Но я склонен использовать virtualenv для проектов, где я имею жесткий контроль над сценарием развертывания. В тех случаях, когда у меня нет жесткого контроля, я склонен использовать описанный выше подход. Это позволяет легко упаковать проект в виде zip и установить его конечным пользователем (путем разархивирования).
Ответ 2
Просто используйте virtualenv - это инструмент для создания изолированных сред Python. Вы можете создать настройку script и распределить всю группу, если хотите.
Ответ 3
"Мне не нравится тот факт, что разработчикам (или мне, начиная с чистой новой машины) приходится перепрыгивать через обрывки distutils, чтобы локально устанавливать библиотеки, прежде чем они смогут начать"
Почему?
Что конкретно - не так с этим?
Вы сделали это, чтобы создать проект. Ваш проект настолько популярен, что другие хотят сделать то же самое.
Я не вижу проблемы. Пожалуйста, уточните свой вопрос с конкретными проблемами, которые вам нужны. Неприятие способа распространения открытого источника не является проблемой - это то, как работает открытый источник.
Edit. "Обнесенный стеной сад" не имеет большого значения.
Выбор 1. Вы можете, BTW, построить "установщик", который запускает easy_install 6 раз для них.
Выбор 2. Вы можете сохранить все комплекты установщика, которые бы использовали easy_install. Затем вы можете предоставить script, который делает unzip и python setup.py install
для всех шести.
Выбор 3. Вы можете предоставить zipped версию вашего site-packages
. После установки Python они распакуют каталог вашего сайта в пакет `C:\Python2.5\lib\site-packages``.
Выбор 4. Вы можете создать свой собственный установщик MSI для вашей среды Python.
Выбор 5. Вы можете разместить свой собственный pypi-подобный сервер и предоставить easy_install, который сначала проверяет ваш сервер.
Ответ 4
Я согласен с ответами Носкло и С. Лотта. (+1 для обоих)
Могу ли я добавить, что то, что вы хотите сделать, на самом деле является ужасной идеей.
Если вы искренне хотите, чтобы люди взламывали ваш код, им нужно будет понять, какие библиотеки задействованы, как они работают, каковы они, откуда они берутся, документацию для каждого и т.д. Конечно, им предоставляется загрузочный файл script, но помимо этого вы будете мотивированы до такой степени, что они невежественны.
Тогда возникают определенные проблемы, такие как "что, если один пользователь хочет установить другую версию или реализацию библиотеки?", ярким примером здесь является ElementTree, так как это имеет ряд реализаций.
Ответ 5
Я не предполагаю, что это отличная идея, но обычно то, что я делаю в таких ситуациях, это то, что у меня есть Makefile, проверенный в subversion, который содержит правила make для извлечения всех зависимых библиотек и их установки. Makefile может быть достаточно умным, чтобы применять зависимые библиотеки только в том случае, если они отсутствуют, поэтому это может быть относительно быстро.
Новый разработчик проекта просто проверяет из подрывной деятельности и затем набирает "make".
Этот подход может сработать для вас, учитывая, что ваша аудитория уже привыкла к идее использования проверок subversion в рамках процесса их извлечения. Кроме того, он обладает прекрасным свойством, что все знания о вашей программе, включая ее внешние зависимости, записываются в репозиторий исходного кода.