Debitoor is hiring. No bureaucracy, no legacy code, no bullshit, fury continuous deployment, trips #js #node #react #mongo
×Закрыть

Расширяемые приложения на python (setuptools)

Часто разработчики (в том числе на Питоне) сталкиваются с тем,что разные пользователи имеют разные, зачастую противоречивые требования к функциональности приложения.

Обычный выход в такой ситуации — разработать интерфейс (API), который позволит строго определенным образом модифицировать поведение приложение и подстраиваться под нужды пользователей. Расширения, написанные под такой API называются «плагины» (plugins).

Однако разработка API и плагинов, которые их используют, это только пол-дела. Необходимо еще разработать механизм установки и активации этих расширений для конкретно взятой инсталляции приложения. Учитывая, что требовать от пользователя навыков программирования или знания python — явный перебор, способ это должен быть максимально простым.

До появления setuptools эта задача решалась каждым приложением по разному. В этой статье речь пойдет о способе, реализованном setuptools. Благо, практически повсеместное распространение этой библиотеки и превращение в де-факто стандарт дает этому способу неоспоримые преимущества.

Главное: setuptools дает достаточно простой с точки зрения разработчика и очень удобный с точки зрения пользователя механизм описания, установки и использования расширений (плагинов). При этом (что тоже важно!) не вносится никаких ограничений/требований по интерфейсу, которому должны удовлетворять плагины: это может быть duck typing, zope.interface, наследование базового класса приложения или любой другой вариант.
Для пользователя все выглядит максимально просто. Пользователь всего лишь устанавливает нужное расширение при помощи easy_install и получает новую функциональность в своем приложении. Пример: просто установив плагин для nose+vim (easy_install nose-machineout) при запуске nosetests вам будет доступен новые ключи командной строки.

Для разработчика расширений все чуть менее просто, если он уже использует setuptools. Если не использует — чуть похуже, так как придется создать setup.py с нуля. Чтобы ваше расширение было успешно найдено и загружено приложением необходимо описать т.н. точки расширения в setup.py. Пример:

entry_points = {
'nose.plugins': [
'foobar = someplugin:MyNosePlugin'
]
},
В этом примере определяется расширение с именем foobar, которое может быть найдено по имени MyNosePlugin в пакете (модуле) someplugin. Плагин этот можно найти по точке расширения nose.plugins. В детали синтаксиса я углубляться не буду, их можно найти в документации setuptools.

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

for ep in pkg_resources.iter_entry_points('nose.plugins'):
plug = ep.load()
Для примера выше, plug будет классом/функцией MyNosePlugin. Что с ним делать дальше — целиком на совести разработчика. Можно внести в глобальный реестр, проверить на соотв. какому-либо интерфейсу, инстанцировать класс и т.д.
Как видите, все достаточно просто и уже активно используется. Вот только несколько примеров: nose, Trac, TurboGears. При этом функциональность расширений ограничена только воображением разработчика. А скучную работу по «связке» приложения и его расширений возьмет на себя setuptools.
  • Популярное

1 комментарий

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

Подписаться на комментарии