Разработка плагина, который зависит от внешней библиотеки Python

29

Я разрабатываю плагин Python, целью которого является интеграция в QGIS функциональности библиотеки PyPI Python, называемой «возвышением».

Существует ли независимый от ОС способ установки внешних библиотек Python и обеспечения их доступности для плагинов Python?

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

Что я уже знаю

Поиски в Интернете и другие подобные вопросы, похоже, не существует независимого от ОС решения.

Пользователи Windows

Python упакован и распространяется внутри пакета QGIS, поэтому для установки внешних библиотек Python вам нужно пройти через оболочку OSGeo4W и использовать pip оттуда.

Ссылки по теме:

Пользователи OS X

В этом случае QGIS использует встроенный Python, который предварительно упакован в OS X и расположен по адресу:

/usr/bin/python

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

Быстрый обходной путь - использовать home-brew для установки Python, чтобы ваш пип мог работать с изменяемой пользователем платформой Python. Подробности этого подхода смотрите здесь .

После установки всех библиотек Python через pip, вам просто нужно добавить их каталоги в переменную PATH.

Альтернативный способ для пользователей OS X

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

import sys
import pip
pip.main(['install','--target=/Devel/test', 'elevation'])
sys.path.append("/Devel/test")

Самодельное, но работающее решение (протестировано на Linux и OS X)

Я решил пойти по другому пути, поскольку он позволяет отделить обновление библиотеки и обслуживание от плагина. Каждый раз, когда новый пользователь устанавливает плагин, последняя версия библиотеки высот напрямую загружается и устанавливается с помощью pip в подкаталоге плагина.

self.plugin_dir = os.path.dirname(__file__)
self.elevation_dir = os.path.join(self.plugin_dir, 'elevation')

# Checking the presence of elevation library
try:
    import elevation
except:
    pip.main(['install', '--target=%s' % self.elevation_dir, 'elevation'])
    if self.elevation_dir not in sys.path:
        sys.path.append(self.elevation_dir)
Инженер-G
источник
Эта процедура предназначена только для Windows , так как ОС UNIX (Linux, Mac OS X) использовать стандартную версия Python установлена
ген
Я знаю это, я «обогащал» свой вопрос, теперь есть раздел пользователей OS X, который объясняет, как это сделать на Mac.
Инженер-G
1
Вы можете прекрасно установить pip в Apple Python. QGIS использует эту версию, а не другие версии (Homebrew, Anaconda и другие). Если вы хотите использовать Homebrew Python, вам нужно установить Homebrew версию QGIS
gene
также посмотрите на зависимости плагинов , возможен ли плагин pipinstall? Первое: в чем разница между оболочкой Osgeo4w? и много других сообщений в списках QGIS
ген
3
Если это чистая библиотека Python, вы можете просто распространять стороннюю библиотеку со своим плагином в качестве подпакета / модуля.
user2856

Ответы:

2

Я столкнулся с этой проблемой при запуске скриптов Python в QGIS, который зависит от внешней библиотеки Python. Наиболее простым решением является установка Boundless Desktop, который поставляется с командной строкой и устанавливает собственный Python. Используя командную строку, вы можете запустить и установить (используя pip) любой внешний пакет python.

osmjit
источник
1

Я немного поработал над этим недавно над проектом. К сожалению, на самом деле не очень хороший способ достичь этого. Ваше решение очень похоже на то, что я придумал, но нет никакой гарантии, что пользователь даже установил pip.

Я закончил тем, что включил копию get_pip.py и использовал execfile (), чтобы запустить его в случае, когда он недоступен.

Похоже на ваше окончательное решение:

self.plugin_dir = os.path.dirname(__file__)

try:
    import pip
except:
    execfile(os.path.join(self.plugin_dir, get_pip.py))
    import pip
    # just in case the included version is old
    pip.main(['install','--upgrade','pip'])

try:
    import somelibrary
except:
    pip.main(['install', 'somelibrary'])

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

Джесси Макмиллан
источник
1

Это сработало для меня (в def run (self)):

    def load_libraries(self):
        import_path = os.path.join(self.plugin_dir, 'lib/python2.7/site-packages')
        sys.path.insert(0, import_path)

и создание virtualenv.

С Windows это, кажется, другая история. У меня были проблемы с установкой matplotlib.

geekdenz
источник