Sviluppo di un plugin che dipende da una libreria Python esterna


29

Sto sviluppando un plugin Python, l'obiettivo sta integrando in QGIS le funzionalità di una libreria Pyon Pyton chiamata 'elevazione'.

Esiste un modo indipendente dal sistema operativo per installare librerie Python esterne e renderle disponibili per i plugin Python?

Conosco già le diverse procedure specifiche del sistema per l'installazione di una dipendenza Python esterna, quello che mi piacerebbe fare è distribuire il mio plugin in diversi ambienti senza far impazzire la gente.

Quello che già so

Cercando sul Web e altre domande simili sembra che non ci sia una soluzione indipendente dal sistema operativo.

Utenti Windows

Python è impacchettato e distribuito all'interno del pacchetto QGIS, quindi per installare librerie Python esterne devi passare attraverso la shell OSGeo4W e usare pip da lì.

Link correlati:

Utenti OS X.

In questo caso QGIS utilizza il Python integrato che è preconfezionato all'interno di OS X e si trova in:

/usr/bin/python

Il problema qui è che il pip installato predefinito presenta alcune limitazioni e richiede troppi privilegi.

Una soluzione rapida è utilizzare home-brew per installare Python in modo che il pip possa essere eseguito su un framework Python modificabile dall'utente. Vedi i dettagli di questo approccio qui .

Dopo aver installato tutte le librerie Python tramite pip, devi solo aggiungere le loro directory alla variabile PATH.

Modo alternativo per gli utenti di OS X.

All'interno del codice Python del plugin è possibile utilizzare il pip fornito dal sistema per installare i pacchetti richiesti. Quindi è possibile rendere raggiungibile il pacchetto appena installato aggiungendolo al percorso.

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

Soluzione casalinga ma funzionante (testata su Linux e OS X)

Ho deciso di optare per il modo alternativo poiché consente di mantenere l'aggiornamento e la manutenzione della libreria separati dal plug-in. Ogni volta che un nuovo utente installa il plug-in, l'ultima versione della libreria di elevazione viene scaricata e installata direttamente da pip all'interno di una sottodirectory del 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)

Questa procedura è valida solo per Windows perché il sistema operativo Unix (Linux, Mac OS X) utilizza la versione standard di Python installata
gene

Lo so, stavo "arricchendo" la mia domanda, ora c'è una sezione degli utenti di OS X che spiega come farlo su un Mac.
Ingegnere-G,

1
Puoi installare perfettamente pip in Apple Python. QGIS utilizza questa versione e non altre versioni (Homebrew, Anaconda e altre). Se si desidera utilizzare Homebrew Python, è necessario installare la versione Homebrew di QGIS
gene


3
Se si tratta di una libreria Python pura, puoi semplicemente distribuire la libreria di terze parti con il tuo plug-in come pacchetto secondario / modulo.
user2856

Risposte:


2

Ho sofferto di questo problema per eseguire script Python in QGIS che dipende da una libreria Python esterna. La soluzione più semplice è installare Boundless Desktop che viene fornito con la riga di comando e installa il proprio python. Utilizzando la riga di comando è possibile eseguire e installare (usando pip) qualsiasi pacchetto esterno di Python.


1

Ci ho lavorato un po 'su un progetto di recente. Sfortunatamente non c'è davvero un ottimo modo per raggiungere questo obiettivo. La tua soluzione è molto simile a quella che mi è venuta in mente, ma non c'è garanzia che l'utente abbia installato pip.

Ho finito per includere una copia di get_pip.py e usare execfile () per eseguirlo nel caso in cui non fosse disponibile.

Simile alla tua soluzione finale:

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

Un'alternativa, ovviamente, sarebbe quella di includere la libreria stessa nella directory del tuo plugin. Rischi di fornire una versione precedente, ma teoricamente non importa.



1

Questo ha funzionato per me (in 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 configurare un virtualenv.

Con Windows sembra essere una storia diversa però. Ho avuto problemi con l'installazione di matplotlib.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.