Создание Дружбы Между Python И Bash: Библиотеки Smart-Env И Python-Shell

Всем добрый день.

Сегодня Python — один из наиболее используемых языков в сфере создания не только самих программных продуктов, но и обеспечения их инфраструктуры.

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

Однако Bash и Python исповедуют разные подходы к написанию кода и имеют определенные особенности, а значит, портирование Bash-скриптов на «змеиный язык» иногда оказывается емкой и далеко не тривиальной задачей.

Чтобы облегчить жизнь девопсам, на Python создано и продолжает создаваться множество полезных библиотек и утилит. В этой статье описаны две новые библиотеки, созданные автором этого поста — умная среда И оболочка Python — и призван избавить девопсов от необходимости уделять много внимания тонкостям работы с Python, оставив место для более интересных задач.

Сфера деятельности библиотек — переменные среды и запуск внешних утилит. Кому интересно, смотрите кат.



Новые «велосипеды»?

Казалось бы, зачем создавать новые пакеты для вполне обычных операций? Что мешает вам использовать os.environ и subprocess. напрямую? Доказательства в пользу каждой из библиотек приведу отдельно.



библиотека смарт-окружения

Прежде чем писать свое детище, полезно зайти в интернет и поискать готовые решения.

Конечно, есть риск не найти то, что нужно, но это скорее «страховой случай».

Как правило, такой подход работает и экономит много времени и сил.

В соответствии с результатами поиск выяснилось следующее:

  • есть пакеты, которые фактически оборачивают вызовы os.environ, но при этом требуют кучу отвлекающих действий (создание экземпляра класса, специальные параметры в вызовах и т.д.);
  • Есть хорошие пакеты, которые, однако, жестко привязаны к конкретной экосистеме (в основном веб-фреймворки типа Django) и поэтому без файла совсем не универсальны;
  • редки попытки сделать что-то новое.

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

      
      
       

    get_<typename>(var_name)

    Или здесь еще одно решение , который, однако, не поддерживает ныне опальный Python 2 (который, несмотря на официальный Р.

    И.

    П.

    , там еще горы написанного кода и целые экосистемы);

  • Есть школьно-студенческие поделки, которые по непонятным причинам оказались в апстриме PyPI и создают лишь проблемы с именованием новых пакетов (в частности, имя «smart-env» — вынужденная мера).

И этот список можно продолжать долго.

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

Требования, которые были заданы перед написанием smart-env:

  • Самая простая схема использования
  • Легко настраиваемая поддержка типизации данных
  • Совместимость с Python 2.7
  • Хорошее покрытие кода тестами
В конечном итоге все это было реализовано.

Вот пример использования:

from smart_env import ENV print(ENV.HOME) # Equals print(os.environ['HOME']) # assuming you set env variable MYVAR to "True" ENV.enable_automatic_type_cast() my_var = ENV.MY_VAR # Equals boolean True ENV.NEW_VAR = 100 # Sets a new environment variable

Как видно из примера, для работы с новым классом его достаточно просто импортировать (экземпляр создавать не нужно — минус лишние действия).

Доступ к любой переменной окружения достигается обращением к ней как к переменной класса ENV, что, по сути, делает этот класс интуитивной оберткой для родного системного окружения, одновременно превращая его в возможный объект конфигурации практически для любой системы ( аналогичный подход, например, реализован в Django, только там объектом конфигурации является сам модуль/пакет настроек).

Включение/выключение режима поддержки автоматического набора текста осуществляется двумя методами — Enable_automatic_type_cast() и Disable_automatic_type_cast().

Это может быть удобно, если переменная среды содержит сериализованный JSON-подобный объект или даже просто логическую константу (явная установка переменной DEBUG в Django путем сравнения переменной среды с «действительными» строками — один из наиболее распространенных случаев).

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

:) В целом типизация работает прозрачно и поддерживает практически все доступные встроенные типы данных (frozenset, complex и bytes не проверялись).

Требование поддержки Python 2 было реализовано практически без жертв (отказ от типизации и некоторых «леденцов» последних версий Python 3), в частности благодаря вездесущей шестёрке (для решения проблем использования метаклассов) .

Но есть некоторые ограничения:

  • Поддержка Python 3 означает версию 3.5 и выше (их наличие в вашем проекте — результат либо лени, либо отсутствия необходимости в доработках, так как сложно придумать объективную причину, почему вы до сих пор на 3.4);
  • В Python 2.7 библиотека не поддерживает десериализацию заданных литералов.

    Описание здесь .

    Но если кто-то захочет это реализовать, милости просим :);

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

Если строку не удалось распознать ни одним из доступных анализаторов, значение остаётся строкой (скорее, из соображений удобства и обратной совместимости с обычной логикой работы переменных в Bash).



библиотека оболочки Python

Теперь расскажу о второй библиотеке (опущу описание недостатков существующих аналогов - она аналогична описанной для smart-env. Аналоги - здесь И здесь ).

В целом идея реализации и требования к ней аналогичны описанным для smart-env, как видно из примера:

from python_shell import Shell Shell.ls('-l', '$HOME') # Equals "ls -l $HOME" command = Shell.whoami() # Equals "whoami" print(command.output) # prints your current user name print(command.command) # prints "whoami" print(command.return_code) # prints "0" print(command.arguments) # prints "" Shell.mkdir('-p', '/tmp/new_folder') # makes a new folder

Идея такова:

  1. Единственный класс, представляющий Bash в мире Python;
  2. Каждая команда Bash вызывается как функция класса Shell;
  3. Параметры для каждого вызова функции затем передаются в соответствующий вызов команды Bash;
  4. Каждая команда выполняется «здесь и сейчас» в момент ее вызова, т.е.

    работает синхронный подход;

  5. можно получить доступ к выводу команды в стандартный вывод, а также к ее коду возврата;
  6. Если команды нет в системе, выдается исключение.

Как и в случае со smart-env, здесь есть поддержка Python 2 (хотя потребовалось немного больше жертвенной крови) и нет поддержки Python 3.0-3.4.

Планы развития библиотеки

Вы можете использовать библиотеки уже сейчас: обе они размещены на официальном сайте PyPI. Исходники доступны на Github (см.

ниже).

Обе библиотеки будут разрабатываться с учетом отзывов заинтересованных лиц.

И, если в smart-env придумать множество новых возможностей может быть сложно, то в python-shell определенно есть что добавить:

  • поддержка неблокирующих звонков;
  • возможность интерактивного общения с командой (работа со стандартным вводом);
  • добавление новых свойств (например, свойства для получения вывода из stderr);
  • реализация каталога доступных команд (для использования с функцией dir());
  • и т. д.


Ссылки

  1. библиотека смарт-окружения: Гитхаб И ПиПИ
  2. библиотека оболочки Python: Гитхаб И ПиПИ
  3. Telegram-канал обновления библиотеки
UPD от 23.02.2020: * Репозитории перенесены, соответствующие ссылки обновлены.

* Версия python-shell==1.0.1 готовится к выпуску 29.02.2020. Изменения включают поддержку автозаполнения команд и команды dir(Shell), запуск команд с неверным идентификатором Python и исправления ошибок.

UPD от 01.03.2020: * Пост о следующем выпуске.

Теги: #python #DevOps #bash #python3 #переменные среды #python2 #python2

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.