Desenvolvimento de um plugin que depende de uma biblioteca Python externa

29

Estou desenvolvendo um plug-in Python, o objetivo é integrar ao QGIS as funcionalidades de uma biblioteca PyPI Python chamada 'elevação'.

Existe uma maneira independente do SO de instalar bibliotecas externas do Python e disponibilizá-las para os plugins do Python?

Eu já conheço os diferentes procedimentos específicos do sistema para instalar uma dependência externa do Python. O que eu gostaria de fazer é distribuir meu plug-in em diferentes ambientes sem deixar as pessoas loucas.

O que eu já sei

Pesquisando na web e outras perguntas semelhantes, parece que não há uma solução independente do SO.

Usuários do Windows

O Python é empacotado e distribuído dentro do pacote QGIS; portanto, para instalar bibliotecas externas do Python, você precisa passar pelo OSGeo4W Shell e usar o pip a partir daí.

Links Relacionados:

Usuários do OS X

Nesse caso, o QGIS usa o Python embutido, pré-empacotado no OS X e localizado em:

/usr/bin/python

O problema aqui é que o pip instalado padrão tem algumas limitações e requer muitos privilégios.

Uma solução rápida é usar o home-brew para instalar o Python, para que seu pip possa ser executado em uma estrutura Python modificável pelo usuário. Veja os detalhes dessa abordagem aqui .

Após instalar todas as bibliotecas Python via pip, você só precisa adicionar seus diretórios à variável PATH.

Maneira alternativa para usuários do OS X

Dentro do código Python do plug-in, você pode usar o pip fornecido pelo sistema para instalar os pacotes necessários. Então você pode tornar acessível o pacote recém-instalado, adicionando-o ao caminho.

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

Solução caseira, mas funcional (testada no Linux e OS X)

Decidi seguir o caminho alternativo, pois permite manter a atualização e a manutenção da biblioteca separadas do plug-in. Sempre que um novo usuário instala o plug-in, a versão mais recente da biblioteca de elevação é baixada e instalada diretamente pelo pip dentro de um subdiretório do plug-in.

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)
Engenheiro-G
fonte
Este procedimento é apenas para Windows porque o sistema operacional Unix (Linux, Mac OS X) usa a versão padrão do Python instalada
gene
Eu sei disso, eu estava 'enriquecendo' minha pergunta, agora existe uma seção de usuários do OS X que explica como fazê-lo em um Mac.
Engineer-G
1
Você pode instalar perfeitamente o pip no Apple Python. O QGIS usa esta versão e não outras (Homebrew, Anaconda e outras). Se você quiser usar o Homebrew Python, precisará instalar a versão Homebrew do QGIS
gene
3
Se for uma biblioteca python pura, você pode simplesmente distribuir a biblioteca de terceiros com seu plug-in como um subpacote / módulo.
precisa saber é o seguinte

Respostas:

2

Eu sofri com esse problema para executar scripts Python no QGIS, que depende de uma biblioteca Python externa. A solução mais direta é instalar o Boundless Desktop que acompanha a linha de comando e instala seu próprio python. Usando a linha de comando, você pode executar e instalar (usando pip) qualquer pacote externo de python.

osmjit
fonte
1

Eu trabalhei nisso um pouco em um projeto recentemente. Infelizmente, não há realmente uma ótima maneira de conseguir isso. Sua solução é muito semelhante à que eu criei, mas não há garantia de que o usuário tenha o pip instalado.

Acabei incluindo uma cópia de get_pip.py e usando execfile () para executá-la no caso em que não está disponível.

Semelhante à sua solução final:

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'])

Uma alternativa, é claro, seria incluir a própria biblioteca no diretório do seu plugin. Você corre o risco de fornecer uma versão antiga, mas teoricamente isso não importa.

Jesse McMillan
fonte
1

Isso funcionou para mim (em 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)

e configurando um virtualenv.

No Windows, parece ser uma história diferente. Tive problemas para instalar o matplotlib.

geekdenz
fonte