0,0
рейтинг
1 февраля 2015 в 18:39

Разработка → Pundle — bundler для python

Начну с пиара другого проекта, который мне очень нравится использовать — pyenv. Это порт rbenv для python, который служит для установки нужных версий python в папку пользователя в недра ~/.pyenv, и активации нужной версии руками или, что более грамотно, через файл .pyenv-version в папке проекта.

Следуя этой старой доброй традиции обмениваться здравыми идеями с ruby сообществом, я решил портировать идею Bundler (http://bundler.io/), и назвал его Pundle. Это вторая часть рабочего процесса связанного с версиями интерпретаторов и пакетов в руби, и как и первая, достаточно разумна.

Главная идея pundle в том, чтобы не создавать отдельную директорию на каждую комбинацию версий пакетов как в virtualenv, а вместо этого поставить все пакеты в директории типа .pundlerdir/python-version-variant/package-name-2.3.4, и при старте проекта, взяв информацию из frozen.txt, активировать нужные версии пакетов



Это плохо работает с пакетами которые пытаются делать всякие хитрости с раскладыванием .pth файлов в site-packages, но отлично работает с нормальными вариантами. А их подавляющее большинство, ну про хитрые есть время придумать как с ними быть.

Итак, поиграемся:

  > brew install pyenv
  > pyenv install 3.4.1
  > pyenv shell 3.4.1
  > python --version
  Python 3.4.1


Отлично, нужная версия интерпретатора! Вы же уже начали переходить на третью версию чтобы переломить тенденцию к медленному умиранию языка? Тогда следуем дальше, вдохнем больше новизны и создадим файл requirements.txt с содержимым:

  trafaret > 0.5
  nomad > 1.8


Ну а теперь запустим pundle:

  > pip install pundle
  ...
  > python -m pundle
  Install some packages
  ... много буков, символов, междометий, медитация


На данном этапе мы поставили пакеты и получили файл frozen.txt.

  nomad==1.9           # nomad << requirements file
  opster==4.1          # opster>=4.0 << nomad << requirements file
  termcolor==1.1.0     # termcolor << nomad << requirements file
  trafaret==0.5.3      # trafaret << requirements file


Получили два пакета, которые хотели, и пару в нагрузку как зависимости nomad (тоже хорошая штука, но Саша про нее лучше жгет сам).

Дальше у нас есть два варианта — первый это в файле, которым мы планируем запускать наш проект руками импортировать pundle и попросить его активировать нужные версии проектов.

Я же предпочитаю команду fixate чтобы добавить активацию нужных версий пакетов в usercustomize.py:
  > python -m pundle fixate


С этого момента мы можем запускать интерпретатор и автоматически иметь доступ к нужным версиям пакетов:

  > python
  >>> import nomad
  >>> nomad.__version__
  '1.9'


pyenv тут github.com/yyuu/pyenv
pundle тут github.com/Deepwalker/pundler

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

Я с удовольствием использую оба проекта в реальной работе, и мне очень нравится не возиться с virtualenv и версиями интерпретатора. Но мне немного скучно использовать pundle одному, поэтому я взялся за пиар и приглашаю всех изменить рабочий процесс современного питонера на новый и продвинутый.
Кривушин Михаил @Deepwalker
карма
18,7
рейтинг 0,0
Программист
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (21)

  • +1
    На сервере смысла нет в пяти питонах и в семи джанго.

    Разработчику тоже столько не надо.
    Достаточно одной рабочей связки, а все остальное можно оставить для tox.
    • +2
      Не совсем так — если у вас много проектов, то там свои заморочки и могут быть не совсем совместимые версии пакетов. Ну и разные версии питона уж 100% — современные реалии.
      Это конечно на аутсорсе заметнее, когда у тебя то один проект, то тот что вы полгода назад сдали выплывает за фиксами — такое вот оно.
    • 0
      Смотря какой сервер. Если на одной виртуалке крутится ряд полузаброшенных проектов разных лет, такая ситуация вполне возможна. Не говорю, что это — хорошо, но замечу что вопрос оправданности и вопрос возможности возникновения ситуации — это существенно разные вопросы.
  • +1
    а есть где-нибудь уже готовое обобщение фатальных недостатков связки системного python + pip + virtualenv?
    я, наверное, недостаточно c ними работал, но вкратце пообщавшись с rvm+bundler решил, что мне они нравятся гораздо меньше. ладно еще в разработке, но в руби-мире принято тащить rvm на production…

    и да, если бы мне хотелось на одной машине хостить приложения с разными версиями питона, я бы взял docker.
    • 0
      Про «принято в руби мире» давайте не будем, вы были в каком-то плохом его варианте ;) Давайте по теме.

      Возможно ли, что virtualenv в принципе странная вещь? Что это такое — это такая папка, куда питон пакеты по старинке валят всё что им угодно. Как-то откатывать версии пакетов или гарантировано удалить из этой среды какой-то пакет невозможно. Гарантировать что эта папка не сломается просто в один прекрасные день — тоже.

      У меня бывали ситуации, неоднократно, когда virtualenv приходилось сносить и ставить всё заново. Это боль, это долго и неприятно.

      pip+virtualenv никак мне не трекают что за версии пакетов они там наставили — pip freeze выдает какую-то фигню. Каждый пакет прописывать руками в requirements.txt с ``==`` мне лично странно.

      В общем тут с моей точки зрения просто — припомните на самом ли деле всё так у вас безоблачно с virtualenv? Действительно pip дотягивает до bundler? Максимум до gem. И так ли уж ужасен был опыт с bundler?
      • +1
        Меня связка pip+virtualenv+wheel устраивает и работает довольно стабильно. Я один раз компилирую пакеты в wheel, а wheel остаются закешироваными в. Поэтому сосздание нового venvа с нуля занимает пару минут:

        $ mkvirtualenv x
        $ pip install wheel
        $ pip install -r requirements.txt
        


        В .bash_profile у меня что-то такое:

        PIP_REQUIRE_VIRTUALENV=true
        PIP_CACHE_DIR=/Users/x/.pip/cache
        PIP_WHEEL_DIR=/Users/x/.pip/wheel
        PIP_FIND_LINKS=/Users/x/.pip/wheel /Users/x/.pip/cache
        PIP_USE_WHEEL=YES
        


        И да, стоит у меня еще pipvirtualenvwrapper для удобства.

        Раз в какое-то время запускаю в бэкграунде pip wheel -r requirements.txt && pip install -U -r requirements.txt и получаю новые версии пакетов.

        • 0
          Как быть с frozen? Никогда не бывало ситуации, что вот вы сделали фичу у себя локально, а пакет вот прям гвоздями не прибивали. Делаете деплой на сервер, а там новый пакет разносит все к черту? Ну если у вас не бывало, то у меня вот бывало и неприятно прям.

          Это означает что flow сломан и никакими колесами его не починить.
          • +1
            Нет, не бывало, именно потому, что пакет для деплоя прибиваю в requirements вместе с его зависимостями гвоздями (==x.y.z).
            • 0
              А как тогда у вас новые версии пакетов получаются? Если они в requirements.txt прибиты гвоздями, то "-U" ничем не должен помочь.

              И как вы их прибиваете? Руками вписываете нужные версии?
              • +2
                Использую такое в requirements.tx

                Django>=1.7, <1.8


                Для последней версии в ветке 1.7, но не ветка 1.8 (мало ли чего там).
                • 0
                  Ну в случае django может сработать, при другой схеме выставления версий может не прокатить.
                  Плюс все равно не гарантирует — разрабатываете и тестируете на одной версии, а на какой оно будет работать в production, неизвестно.

                  Еще не совсем понятно как быть с зависимостями. Всё это куча ручной работы, да к тому же не гарантирующей результат.

                  Плюс еще невнятные конструкции из кучи виртуалэнвов.

                  Это точно нормальное решение или мы, питоняшки, слишком не любим ничего менять?
                  • 0
                    Не могу говорить за всех «питонщиков», но у нас на продакшем всегда выкатывается "==" версия requirements.txt. При этом проблем с зависимостями никогда не испытывал. На дев сервере все настраивается так, как нужно нам, после этого делается

                    pip freeze > requirements.txt

                    Выгружается все с "==" версиями. Выгружаются все установленные в локальном venv пакеты, а это уже решенные зависимости. Достаточно держать в порядке свой venv и никаких проблем не будет.

                    Если я когда-то и испытывал с этим проблемы, то они были настолько незначительными, что благополучно забыты.

                    Для меня с venv работают два пунтка из общей идеалогии:

                    1. Явное лучше, чем неявное.
                    2. Сложное лучше, чем запутанное.

                    Все устанавливаемые пакеты указаны явно. Да, это иногда кажется сложным, избыточным и нужно внимательно вчитаться в список, выдаваемый freeze, но там количество «магии» сведено к минимуму. Если я вижу то, чего не понимаю в этом списке, то это повод пойти и изучить данный пакет, узнать откуда он там появился, кто его притащил за собой и почему оно мне надо.

                    Для меня магия руби иногда переваливает порог внутреннего допустимого лимита. Да, это прекрасно, что оно все умеет само, что оно все за тебя решит. Но когда оно не сможет…
                    • 0
                      Вы почему то решили, что если работает как надо, то оно неявное и запутанное и магия. На самом деле оно просто менее муторное и исключает возможность наломать дров руками перебирая строчки в важном файле.

                      В Pundle нет магии, он прямой как стрела, он просто помогает разработчику точно трекать версии пакетов, на которых шла разработка.

                      И при чем тут руби магия кстати?

                      Ну и к venv я бы ваши два пункта не применял, вы его код не видели и вообще посмотрите в его внутренности.
                      • 0
                        В Pundle нет магии, он прямой как стрела, он просто помогает разработчику точно трекать версии пакетов, на которых шла разработка.

                        Venv помогает делать то же самое. Работает по-другому, спору нет, но решает ровно ту же проблему.

                        И при чем тут руби магия кстати?

                        Да ни при чем, просто вспомнил свой опыт работы с рельсами.

                        Ну и к venv я бы ваши два пункта не применял, вы его код не видели и вообще посмотрите в его внутренности.

                        Смотрел, проморгался и теперь вглядываюсь в сторону контейнеров.

                        Но все же, спасибо за инструмент. Обязательно попробую Pundle в ближайшее время.
      • 0
        вы были в каком-то плохом его варианте

        Ну, вокруг меня в офисе сидят 6 человек, которые пишут под рельсы и свято верят, что rvm на продакшене — самое то. Я за что купил, за то продал. =)

        папка, куда питон пакеты по старинке валят всё что им угодно

        Ну, блин. Это претензия уже то ли к самому питону, то ли к setuptools. Везде, где есть питон, есть такая папка, только иногда в нее валят все что попало через sudo.

        virtualenv приходилось сносить и ставить всё заново

        pip freeze выдает какую-то фигню

        Я с этим не сталкивался. pip, конечно, выдает явно больше информации, чем нужно, он в этом плане туповат. Разделять dev-deps от prod-deps неудобно, согласен.
        Для упрощения можно было бы добавить ключ --save у pip install, который бы автоматом дописал соответственное package==version в указанный файл — кстати, странно, что его до сих пор нет.

        И так ли уж ужасен был опыт с bundler?

        Против bundler я ничего пока не имею, и не буду иметь, надеюсь. Страдал я больше от rvm и, увидев pyenv, сразу же это вспомнил. Слишком свежие болезненные впечатления.

        Вообще, я против самой идеи ничего не имею. Если реализация будет работать хорошо и без лишней магии — замечательно.
        • 0
          pip кстати, насколько я помню, просто по site-packages с помощью pkg_resources прошвыривается и все пакеты которые нашел потом вот и выводит.
          И есть несколько проектов которые нацелены именно на создание такого файлика с прибитыми зависимостями. Но мне мало, я хочу чтобы вообще всё всё всё само делалось! :)
        • +1
          Так вы продайте вашим разрабам chruby, или на худой конец rbenv. RVM конечно монстр, и устарел — но многие до сих пор по банальной инерции им пользуются.
          • 0
            Ну в продакшн тем не менее не надо ни первый ни второй — все таки лучше пакет собрать правильный под целевой дистрибутив. Тем более что их уже насобирали и они есть на любые версии ruby и под ubuntu и под centos/redhat.

            Это я уточнил совет, а то ведь мужики просто сменят инструмент деплоя.
          • 0
            Да черта с два я им что продам, я ж erlang-разработчик, я же не шарю. :)
  • +1
    Странное именование requirements.txt и frozen.txt. В ruby мире Gemfile и Gemfile.lock. В мире python такие названия файлов являются нормой?
    • 0
      Да, старая традиция. Я пробовал как-то использовать Eggfile, но чужеродно все таки смотрится в питоне.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.