Desarrollo de un complemento que depende de una biblioteca externa de Python

29

Estoy desarrollando un complemento de Python, el objetivo está integrando en QGIS las funcionalidades de una biblioteca PyPI Python llamada 'elevación'.

¿Existe una manera independiente del sistema operativo de instalar bibliotecas externas de Python y ponerlas a disposición de los complementos de Python?

Ya conozco los diferentes procedimientos específicos del sistema para instalar una dependencia externa de Python, lo que me gustaría hacer es distribuir mi complemento en diferentes entornos sin hacer que la gente se vuelva loca.

Lo que ya sé

Al buscar en la web y otras preguntas similares, parece que no hay una solución independiente del sistema operativo.

Usuarios de Windows

Python está empaquetado y distribuido dentro del paquete QGIS, por lo que para instalar bibliotecas externas de Python debe pasar por el Shell OSGeo4W y usar pip desde allí.

enlaces relacionados:

Usuarios de OS X

En este caso, QGIS utiliza el Python incorporado que está preempaquetado dentro de OS X y ubicado en:

/usr/bin/python

El problema aquí es que el pip instalado predeterminado tiene algunas limitaciones y requiere demasiados privilegios.

Una solución rápida es usar home-brew para instalar Python para que su pip pueda ejecutarse en un marco de Python modificable por el usuario. Vea los detalles de este enfoque aquí .

Después de instalar todas las bibliotecas de Python a través de pip, solo necesita agregar sus directorios a la variable PATH.

Forma alternativa para usuarios de OS X

Dentro del código de Python del complemento, puede usar el pip proporcionado por el sistema para instalar los paquetes requeridos. Luego puede hacer que el paquete recién instalado sea accesible agregándolo a la ruta.

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

Solución casera pero funcional (probada en Linux y OS X)

Decidí optar por la alternativa, ya que permite mantener la actualización y el mantenimiento de la biblioteca separados del complemento. Cada vez que un nuevo usuario instala el complemento, la última versión de la biblioteca de elevación se descarga e instala directamente mediante pip dentro de un subdirectorio del complemento.

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)
Ingeniero-G
fuente
Este procedimiento es solo para Windows porque el sistema operativo Unix (Linux, Mac OS X) utiliza la versión estándar de Python instalada
gene
Lo sé, estaba 'enriqueciendo' mi pregunta, ahora hay una sección de usuarios de OS X que explica cómo hacerlo en una Mac.
Ingeniero-G
1
Puede instalar perfectamente pip en Apple Python. QGIS usa esta versión y no otras versiones (Homebrew, Anaconda y otras). Si desea utilizar Homebrew Python, debe instalar la versión Homebrew de QGIS
gene
3
Si se trata de una biblioteca de Python pura, simplemente puede distribuir la biblioteca de terceros con su complemento como un subpaquete / módulo.
user2856

Respuestas:

2

Sufrí este problema para ejecutar scripts de Python en QGIS que depende de una biblioteca externa de Python. La solución más sencilla es instalar Boundless Desktop que viene con la línea de comando e instala su propio python. Usando la línea de comando puedes ejecutar e instalar (usando pip) cualquier paquete externo de python.

osmjit
fuente
1

Trabajé en esto un poco recientemente en un proyecto. Lamentablemente, no hay una buena forma de lograrlo. Su solución es muy similar a la que se me ocurrió, pero no hay garantía de que el usuario tenga instalado pip.

Terminé incluyendo una copia de get_pip.py y usando execfile () para ejecutarlo en el caso cuando no está disponible.

Similar a su solución 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'])

Una alternativa, por supuesto, sería incluir la propia biblioteca en el directorio de su complemento. Se arriesga a proporcionar una versión anterior, pero en teoría no importará.

Jesse McMillan
fuente
1

Esto funcionó para mí (en 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)

y establecer un virtualenv.

Sin embargo, con Windows parece ser una historia diferente. Tuve problemas para instalar matplotlib.

geekdenz
fuente