¿Es posible especificar un archivo de secuencia de comandos de Python posterior a la instalación como parte del archivo setuptools setup.py para que un usuario pueda ejecutar el comando?
python setup.py install
en un archivo de archivo de proyecto local, o
pip install <name>
para un proyecto PyPI y el script se ejecutará al finalizar la instalación de las herramientas de configuración estándar? Estoy buscando realizar tareas posteriores a la instalación que se puedan codificar en un solo archivo de secuencia de comandos de Python (por ejemplo, entregar un mensaje personalizado posterior a la instalación al usuario, extraer archivos de datos adicionales de un repositorio de origen remoto diferente).
Me encontré con esta respuesta SO de hace varios años que aborda el tema y parece que el consenso en ese momento era que necesita crear un subcomando de instalación. Si ese sigue siendo el caso, ¿sería posible que alguien proporcione un ejemplo de cómo hacer esto para que no sea necesario que el usuario ingrese un segundo comando para ejecutar el script?
fuente
Respuestas:
Nota: La siguiente solución solo funciona cuando se instala un archivo comprimido o tarball de distribución de código fuente, o se instala en modo editable desde un árbol de código fuente. Será no trabajar cuando se instala desde una rueda binario (
.whl
)Esta solución es más transparente:
Hará algunas adiciones
setup.py
y no es necesario un archivo adicional.También debe considerar dos posinstalaciones diferentes; uno para el modo de desarrollo / editable y el otro para el modo de instalación.
Agregue estas dos clases que incluyen su secuencia de comandos posterior a la instalación para
setup.py
:e inserte el
cmdclass
argumento parasetup()
funcionar ensetup.py
:Incluso puede llamar a comandos de shell durante la instalación, como en este ejemplo que hace la preparación previa a la instalación:
PD: no hay puntos de entrada de preinstalación disponibles en setuptools. Lea esta discusión si se pregunta por qué no hay ninguno.
fuente
install
comando real ?run
al padre , su comando es una instalación posterior, de lo contrario, es una instalación previa. Actualicé la respuesta para reflejar esto.install_requires
dependencias se ignoranpip3
. El script de instalación se ejecutó al publicar el paquete, pero no al instalarlo.Nota: La siguiente solución solo funciona cuando se instala un archivo comprimido o tarball de distribución de código fuente, o se instala en modo editable desde un árbol de código fuente. Será no trabajar cuando se instala desde una rueda binario (
.whl
)Esta es la única estrategia que me ha funcionado cuando el script posterior a la instalación requiere que las dependencias del paquete ya se hayan instalado:
fuente
atexit
controlador en lugar de simplemente llamar a la función posterior a la instalación después del paso de instalación?setuptools
está bastante poco documentado. Otros ya han modificado sus respuestas a estas preguntas y respuestas con las soluciones correctas.atexit
y no redefiniréinstall.run()
(esta es la razón por la que las dependencias ya no se manejan). Además, para conocer el directorio de instalación, he puesto_post_install()
como método denew_install
, qué me permite accederself.install_purelib
yself.install_platlib
(no sé cuál usar, peroself.install_lib
está mal, extrañamente).Nota: La siguiente solución solo funciona cuando se instala un archivo comprimido o tarball de distribución de código fuente, o se instala en modo editable desde un árbol de código fuente. Será no trabajar cuando se instala desde una rueda binario (
.whl
)Una solución podría ser incluir un directorio
post_setup.py
insetup.py
.post_setup.py
contendrá una función que realiza la instalación posterior ysetup.py
solo la importará y ejecutará en el momento adecuado.En
setup.py
:En
post_setup.py
:Con la idea común de iniciar
setup.py
desde su directorio, podrá importar, de lopost_setup.py
contrario, lanzará una función vacía.En
post_setup.py
, laif __name__ == '__main__':
declaración le permite iniciar manualmente la instalación posterior desde la línea de comandos.fuente
run()
hace que las dependencias del paquete no se instalen.cmdclass
se reemplazó el mal , lo he arreglado.post_install()
búsqueda, de loinstall_data.run(self)
contrario, se perderán algunas cosas. Comodata_files
al menos. Gracias kynan.install_data
no se ejecuta en mi caso. Entonces, ¿no tieneatexit
la ventaja de garantizar que el script posterior a la instalación se ejecutará al final, en cualquier situación?Combinando las respuestas de @Apalala, @Zulu y @mertyildiran; esto funcionó para mí en un entorno Python 3.5:
Esto también le da acceso a la ruta de instalación del paquete en
install_path
, para hacer un trabajo de shell.fuente
Creo que la forma más fácil de realizar la posinstalación y mantener los requisitos es decorar la llamada a
setup(...)
:Esto se ejecutará
setup()
al declararsetup
. Una vez que haya terminado con la instalación de los requisitos, ejecutará la_post_install()
función, que ejecutará la función interna_post_actions()
.fuente
Si usa atexit, no es necesario crear una nueva clase cmd. Simplemente puede crear su registro atexit justo antes de la llamada setup (). Hace la misma cosa.
Además, si necesita que se instalen las dependencias primero, esto no funciona con la instalación de pip, ya que se llamará a su controlador atexit antes de que pip mueva los paquetes a su lugar.
fuente
No pude resolver un problema con ninguna de las recomendaciones presentadas, así que esto es lo que me ayudó.
Puede llamar a la función que desea ejecutar después de la instalación justo después
setup()
desetup.py
, así:fuente