Entwicklung eines Plugins, das von einer externen Python-Bibliothek abhängt


29

Ich entwickle ein Python-Plugin, dessen Ziel es ist, die Funktionen einer PyPI-Python-Bibliothek namens "elevation" in QGIS zu integrieren.

Gibt es eine betriebssystemunabhängige Möglichkeit, externe Python-Bibliotheken zu installieren und für die Python-Plugins verfügbar zu machen?

Ich kenne bereits die verschiedenen systemspezifischen Verfahren zum Installieren einer externen Python-Abhängigkeit. Ich möchte mein Plugin auf verschiedene Umgebungen verteilen, ohne dass die Leute verrückt werden.

Was ich schon weiß

Beim Durchsuchen des Webs und anderer ähnlicher Fragen scheint es keine betriebssystemunabhängige Lösung zu geben.

Windows-Benutzer

Python wird im QGIS-Paket gepackt und verteilt. Um also externe Python-Bibliotheken zu installieren, müssen Sie die OSGeo4W-Shell durchgehen und pip von dort aus verwenden.

ähnliche Links:

OS X-Benutzer

In diesem Fall verwendet QGIS das in OS X vorinstallierte Python, das sich unter folgender Adresse befindet:

/usr/bin/python

Das Problem hierbei ist, dass der standardmäßig installierte Pip einige Einschränkungen aufweist und zu viele Berechtigungen erfordert.

Eine schnelle Problemumgehung besteht darin, Python mithilfe von Home-Brew zu installieren, damit Ihr Pip auf einem vom Benutzer veränderbaren Python-Framework ausgeführt werden kann. Einzelheiten zu diesem Ansatz finden Sie hier .

Nachdem Sie alle Python-Bibliotheken über pip installiert haben, müssen Sie nur ihre Verzeichnisse zur PATH-Variablen hinzufügen.

Alternative Möglichkeit für OS X-Benutzer

Innerhalb des Plugin-Python-Codes können Sie den vom System bereitgestellten Pip verwenden, um die erforderlichen Pakete zu installieren. Dann können Sie das gerade installierte Paket erreichbar machen und es dem Pfad hinzufügen.

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

Selbstgemachte, aber funktionierende Lösung (sowohl unter Linux als auch unter OS X getestet)

Ich habe mich für den alternativen Weg entschieden, da dadurch die Aktualisierung und Wartung der Bibliothek vom Plugin getrennt bleiben kann. Jedes Mal, wenn ein neuer Benutzer das Plugin installiert, wird die neueste Version der Elevation-Bibliothek direkt heruntergeladen und von pip in einem Unterverzeichnis des Plugins installiert.

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)

Dieses Verfahren gilt nur für Windows, da das Unix-Betriebssystem (Linux, Mac OS X) die installierte Standard-Python-Version verwendet
Gen

Ich weiß, ich habe meine Frage "bereichert", jetzt gibt es einen Abschnitt für OS X-Benutzer, in dem erklärt wird, wie man es auf einem Mac macht.
Ingenieur-G

1
Sie können pip perfekt in Apple Python installieren. QGIS verwendet diese Version und nicht andere Versionen (Homebrew, Anaconda und andere). Wenn Sie Homebrew Python verwenden möchten, müssen Sie die Homebrew-Version von QGIS
gene am


3
Wenn es sich um eine reine Python-Bibliothek handelt, können Sie die 3rd-Party-Bibliothek einfach mit Ihrem Plugin als Unterpaket / Modul verteilen.
User2856

Antworten:


2

Ich litt unter diesem Problem, Python-Skripte in QGIS auszuführen, das von einer externen Python-Bibliothek abhängt. Die einfachste Lösung ist die Installation von Boundless Desktop, das mit der Befehlszeile geliefert wird und einen eigenen Python installiert. Über die Befehlszeile können Sie jedes externe Python-Paket ausführen und installieren (mit pip).


1

Ich habe kürzlich ein bisschen an einem Projekt gearbeitet. Leider gibt es keinen großartigen Weg, dies zu erreichen. Ihre Lösung ist der von mir entwickelten sehr ähnlich, es gibt jedoch keine Garantie dafür, dass der Benutzer sogar Pip installiert hat.

Am Ende habe ich eine Kopie von get_pip.py hinzugefügt und execfile () verwendet, um sie in dem Fall auszuführen, dass sie nicht verfügbar ist.

Ähnlich wie bei Ihrer endgültigen Lösung:

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

Eine Alternative wäre natürlich, die Bibliothek selbst in das Verzeichnis Ihres Plugins aufzunehmen. Sie riskieren, eine alte Version bereitzustellen, aber theoretisch spielt das keine Rolle.



1

Das hat bei mir geklappt (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)

und Einrichten einer virtuellen Umgebung.

Bei Windows sieht es allerdings anders aus. Ich hatte Probleme bei der Installation von matplotlib.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.