Instalar paquetes de Python desde la carpeta del sistema de archivos local a virtualenv con pip

346

¿Es posible instalar paquetes usando pip del sistema de archivos local?

He ejecutado python setup.py sdistmi paquete, que ha creado el archivo tar.gz apropiado. Este archivo se almacena en mi sistema en /srv/pkg/mypackage/mypackage-0.1.0.tar.gz.

Ahora en un entorno virtual, me gustaría instalar paquetes provenientes de pypi o de la ubicación local específica /srv/pkg.

es posible?

PD : Sé que puedo especificar pip install /srv/pkg/mypackage/mypackage-0.1.0.tar.gz. Eso funcionará, pero estoy hablando de usar la /srv/pkgubicación como otro lugar para buscar pip si escribí pip install mypackage.

chadgh
fuente
Estaba buscando instalar un paquete PyPi sin setup.py, desde WHL wheel, y se instaló después de descargar una versión correcta para mi versión de Python, y ejecuté pip install <Path-to-WHL-file>.
Wiktor Stribiżew

Respuestas:

136

Estoy bastante seguro de que lo que estás buscando se llama --find-linksopción.

Aunque es posible que deba generar un dummy index.htmlpara su índice de paquete local que enumere los enlaces a todos los paquetes. Esta herramienta ayuda a:

https://github.com/wolever/pip2pi

Mikko Ohtamaa
fuente
100
pip install mypackage --no-index --find-links file:///srv/pkg/mypackageDeberia trabajar.
jfs
1
Ayuda Y podemos usar la opción -i de pip para tratarlo como un PyPI local.
diabloneo
El comando equivalente de easy_install eseasy_install --allow-hosts=None --find-links file:///srv/pkg/mypackage mypackage
Wilfred Hughes el
Tuve que crear un archivo de distribución de origen, no solo señalarlo al directorio del proyecto o paquete antes de que funcionara. Esto me hizo tropezar. docs.python.org/3.6/distutils/sourcedist.html
Josh
3
Tenga en cuenta que --find-linksaún permitirá buscar en PyPI si el paquete no se encuentra en la ubicación especificada o si hay una versión más nueva disponible. En Windows, encuentro que combinar esto con --only-binary=packagename(o --only-binary=:all:) es extraordinariamente útil. Esto evita que pip intente descargar cualquier paquete con dependencias nativas que solo tengan distribuciones de origen en PyPI (y por lo tanto requieran compilación), que es la razón más común por la que tengo que intentar instalar desde un directorio. A diferencia --no-index, todavía puedo instalar otros paquetes desde PyPI.
jpmc26
463

Qué pasa::

pip install --help
...
  -e, --editable <path/url>   Install a project in editable mode (i.e. setuptools
                              "develop mode") from a local project path or a VCS url.

p.ej, pip install -e /srv/pkg

donde / srv / pkg es el directorio de nivel superior donde se puede encontrar 'setup.py'.

drpoo
fuente
49
Esto instalará el paquete en modo de desarrollo, lo que significa que solo se vinculará de nuevo a donde están las fuentes. Si por casualidad las fuentes se mueven o eliminan, la importación del paquete fallará.
Trasplazio Garzuglio 01 de
3
@MarcoDinacci Lo interesante --editablees que parece buscar en el directorio del paquete local y establecer la fuente como un repositorio git si hay uno, un poco más flexible que solo una carpeta. Sin embargo, no puedo encontrar documentación para esto.
NotSimon
3
Si bien esto es correcto para instalar un paquete en particular, especialmente uno en desarrollo actual / intensivo en una máquina local o URL de VCS. No responde a la pregunta sobre la búsqueda en un directorio principal de todas las fuentes de paquetes locales en lugar de una fuente de paquetes en particular . La respuesta aceptada funciona cuando tiene un directorio o URL con múltiples paquetes desde los que desea instalar pip.
Gavin
@MarcoDinacci Sin embargo, supongamos que un usuario descarga el código. Lo ponen donde quieren que esté el programa, si son tan inteligentes. ¿Por qué querrían moverlo?
Zelphir Kaltstahl el
1
@ Simon, ¿hay alguna manera de decirle a pip que no busque un repositorio git? Si do pip install -ecomprueba el código desde el control remoto de git, me gustaría instalar el código tal como está (con cambios aún no en el control remoto).
Pedru
39

Estoy instalando pyfuzzypero no está en PyPI; devuelve el mensaje: No matching distribution found for pyfuzzy.

Probé la respuesta aceptada

pip install  --no-index --find-links=file:///Users/victor/Downloads/pyfuzzy-0.1.0 pyfuzzy

Pero tampoco funciona y devuelve el siguiente error:

Ignorando índices: https://pypi.python.org/simple Recopilación de pyfuzzy No se pudo encontrar una versión que satisfaga el requisito pyfuzzy (de las versiones:) No se encontró una distribución coincidente para pyfuzzy

Por fin, he encontrado una buena manera simple allí: https://pip.pypa.io/en/latest/reference/pip_install.html

Install a particular source archive file.
$ pip install ./downloads/SomePackage-1.0.4.tar.gz
$ pip install http://my.package.repo/SomePackage-1.0.4.zip

Entonces el siguiente comando funcionó para mí:

pip install ../pyfuzzy-0.1.0.tar.gz.

Espero que te ayude.

Victor Choy
fuente
44
Esto funcionó para mí. Intenté los otros enfoques y me topé por Could not find a version that satisfieserror. Gracias.
Rair
21

Esta es la solución que terminé usando:

import pip


def install(package):
    # Debugging
    # pip.main(["install", "--pre", "--upgrade", "--no-index",
    #         "--find-links=.", package, "--log-file", "log.txt", "-vv"])
    pip.main(["install", "--upgrade", "--no-index", "--find-links=.", package])


if __name__ == "__main__":
    install("mypackagename")
    raw_input("Press Enter to Exit...\n")

Reuní esto a partir de ejemplos de instalación de pip , así como de la respuesta de Rikard en otra pregunta . El argumento "--pre" le permite instalar versiones que no son de producción. El argumento "--no-index" evita buscar en los índices PyPI. El "--find-links =". Las búsquedas de argumentos en la carpeta local (esto puede ser relativo o absoluto). Usé los argumentos "--log-file", "log.txt" y "-vv" para la depuración. El argumento "--upgrade" le permite instalar versiones más nuevas sobre las anteriores.

También encontré una buena manera de desinstalarlos. Esto es útil cuando tiene varios entornos Python diferentes. Es el mismo formato básico, simplemente usando "desinstalar" en lugar de "instalar", con una medida de seguridad para evitar desinstalaciones no deseadas:

import pip


def uninstall(package):
    response = raw_input("Uninstall '%s'? [y/n]:\n" % package)
    if "y" in response.lower():
        # Debugging
        # pip.main(["uninstall", package, "-vv"])
        pip.main(["uninstall", package])
    pass


if __name__ == "__main__":
    uninstall("mypackagename")
    raw_input("Press Enter to Exit...\n")

La carpeta local contiene estos archivos: install.py, uninstall.py, mypackagename-1.0.zip

Devan Williams
fuente
1
Gracias. El "--find-links =". y "--no-index", donde la clave para unir un script python dentro de mi paquete de utilidad, que primero elimina el paquete de la versión anterior de los paquetes del sitio y luego instala un paquete tar.gz'ed de un subdirectorio de la utilidad-package-folder (no sabía sobre --find-links =.), luego crea la rueda y la instala. Todo automatizado a través de plumbum y clic. Si alguien lo quiere, publicaré un enlace. Votado
JackLeEmmerdeur
15

¡Una opción --find-links hace el trabajo y funciona desde el requirements.txtarchivo!

Puede colocar archivos de paquetes en alguna carpeta y tomar el último sin cambiar el archivo de requisitos, por ejemplo requirements:

.
└───requirements.txt
└───requirements
    ├───foo_bar-0.1.5-py2.py3-none-any.whl
    ├───foo_bar-0.1.6-py2.py3-none-any.whl
    ├───wiz_bang-0.7-py2.py3-none-any.whl
    ├───wiz_bang-0.8-py2.py3-none-any.whl
    ├───base.txt
    ├───local.txt
    └───production.txt

Ahora en el requirements/base.txtpuesto:

--find-links=requirements
foo_bar
wiz_bang>=0.8

Una forma ordenada de actualizar paquetes propietarios, simplemente suelte uno nuevo en la carpeta

De esta manera, puede instalar paquetes desde local folderAND pypicon la misma llamada única:pip install -r requirements/production.txt

PD. Consulte mi bifurcación cookiecutter-djangopackage para ver cómo dividir los requisitos y usar la organización de requisitos basada en carpetas.

Janusz Skonieczny
fuente
¡Gracias, esto es incluso mejor de lo que estaba pensando hacer!
EncontradoNil
11

Desde la página de paquetes de instalación, simplemente puede ejecutar:

pip install / srv / pkg / mypackage

donde / srv / pkg / mypackage es el directorio que contiene setup.py .


Además 1 , puede instalarlo desde el archivo comprimido:

pip install ./mypackage-1.0.4.tar.gz

1 Aunque se señaló en la pregunta, debido a su popularidad, también se incluye.

dim8
fuente
2
Esta debería ser la respuesta predeterminada. No es necesario hacer pip hunt con --find-links si sabe exactamente dónde está su paquete en la máquina local.
Robert
6

Suponiendo que tiene virtualenv y un requirements.txtarchivo, puede definir dentro de este archivo dónde obtener los paquetes:

# Published pypi packages 
PyJWT==1.6.4
email_validator==1.0.3
# Remote GIT repo package, this will install as django-bootstrap-themes
git+https://github.com/marquicus/django-bootstrap-themes#egg=django-bootstrap-themes
# Local GIT repo package, this will install as django-knowledge
git+file:///soft/SANDBOX/python/django/forks/django-knowledge#egg=django-knowledge
marquicus
fuente
5

Tener requisitos en requirements.txty egg_dircomo directorio

puedes construir tu caché local:

$ pip download -r requirements.txt -d eggs_dir

entonces, usar ese "caché" es simple como:

$ pip install -r requirements.txt --find-links=eggs_dir

Sławomir Lenart
fuente
1

Para instalar solo desde local necesita 2 opciones:

  • --find-links: dónde buscar dependencias. No es necesario el file://prefijo mencionado por otros.
  • --no-index: no busque en los índices pypi las dependencias faltantes (dependencias no instaladas y no en la --find-linksruta).

Para que pueda ejecutar desde cualquier carpeta lo siguiente:

pip install --no-index --find-links /srv/pkg /path/to/mypackage-0.1.0.tar.gz

Si su mypackage está configurado correctamente, enumerará todas sus dependencias, y si utilizó la descarga de pip para descargar la cascada de dependencias (es decir, dependencias de dependencias, etc.), todo funcionará.

Si desea utilizar el índice de pipi si es accesible, pero si no utiliza las ruedas locales, puede eliminarlo --no-indexy agregarlo --retries 0. Verá la pausa de pip por un momento mientras intenta verificar que pypi no tenga una dependencia (una no instalada) y cuando encuentre que no puede alcanzarla, volverá a ser local. No parece haber una manera de decirle a pip que "busque primero los locales, luego el índice".

Oliver
fuente
-1

He estado tratando de lograr algo realmente simple y fallé miserablemente, probablemente soy estúpido.

De todos modos, si tiene un script / Dockerfileque descarga un archivo zip del paquete de Python (por ejemplo, desde GitHub) y luego desea instalarlo, puede usar el file:///prefijo para instalarlo como se muestra en el siguiente ejemplo :

$ wget https://example.com/mypackage.zip
$ echo "${MYPACKAGE_MD5}  mypackage.zip" | md5sum --check -
$ pip install file:///.mypackage.zip

NOTA : Sé que puede instalar el paquete de inmediato utilizando, pip install https://example.com/mypackage.zippero en mi caso quería verificar la suma de comprobación (nunca lo suficientemente paranoico) y fallé miserablemente al tratar de usar las diversas opciones que proporciona pip / el #md5fragmento.

Ha sido sorprendentemente frustrante hacer algo tan simple directamente con pip. Solo quería pasar una suma de verificación y pipverificar que el zip coincidía antes de instalarlo.

Probablemente estaba haciendo algo muy estúpido, pero al final me di por vencido y opté por esto. Espero que ayude a otros a intentar hacer algo similar.

Aldo 'xoen' Giambelluca
fuente