Post-installation script avec Python setuptools
est-il possible de spécifier un fichier de script Python post-install dans le cadre des setuptools setup.py fichier pour qu'un utilisateur puisse exécuter la commande:
python setup.py install
sur un fichier local d'archives de projet, ou
pip install <name>
pour un projet PyPI et le script sera lancé à la fin de l'installation standard de setuptools? Je suis à la recherche d'effectuer des tâches post-installation qui peuvent être codées dans un seul fichier de script Python (par ex. après l'installation, un message à l'utilisateur, tirez des fichiers de données supplémentaires à partir d'une autre source à distance référentiel).
je suis tombé sur cette AFIN de répondre à plusieurs années qui aborde le sujet et il semble que le consensus était à cette époque que vous avez besoin pour créer une installation sous-commande. Si c'est toujours le cas, serait-il possible pour quelqu'un de donner un exemple de comment faire en sorte qu'il n'est pas nécessaire pour l'utilisateur de saisir une deuxième commande pour lancer le script?
5 réponses
Cette solution est plus transparente:
vous allez faire quelques ajouts à setup.py et il n'y a pas besoin d'un fichier supplémentaire.
vous devez également considérer deux post-installations différentes; une pour le mode de développement/modifiable et l'autre pour le mode d'installation.
ajoutez ces deux classes qui incluent votre post-installation script à setup.py :
from setuptools import setup
from setuptools.command.develop import develop
from setuptools.command.install import install
class PostDevelopCommand(develop):
"""Post-installation for development mode."""
def run(self):
# PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION
develop.run(self)
class PostInstallCommand(install):
"""Post-installation for installation mode."""
def run(self):
# PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION
install.run(self)
et insérer cmdclass
argument à setup()
fonction dans setup.py :
setup(
...
cmdclass={
'develop': PostDevelopCommand,
'install': PostInstallCommand,
},
...
)
vous pouvez même appeler des commandes shell après l'installation, comme ceci:
from setuptools import setup
from setuptools.command.develop import develop
from setuptools.command.install import install
from subprocess import check_call
class PostDevelopCommand(develop):
"""Post-installation for development mode."""
def run(self):
check_call("apt-get install this-package".split())
develop.run(self)
class PostInstallCommand(install):
"""Post-installation for installation mode."""
def run(self):
check_call("apt-get install this-package".split())
install.run(self)
setup(
...
P. S. Il n'y a aucun point d'entrée pré-installation disponible sur les outils de setuptools. Lisez cette discussion si vous vous demandez pourquoi il n'y en a pas.
C'est la seule stratégie qui a fonctionné pour moi lorsque le script de post-installation exige que les dépendances du paquet aient déjà été installées:
import atexit
from setuptools.command.install import install
def _post_install():
print('POST INSTALL')
class new_install(install):
def __init__(self, *args, **kwargs):
super(new_install, self).__init__(*args, **kwargs)
atexit.register(_post_install)
setuptools.setup(
cmdclass={'install': new_install},
une solution pourrait être d'inclure un post_setup.py
dans le répertoire de setup.py
. post_setup.py
contiendra une fonction qui effectue la post-installation et setup.py
ne l'importera et ne la lancera qu'au moment approprié.
Dans setup.py
:
from distutils.core import setup
from distutils.command.install_data import install_data
try:
from post_setup import main as post_install
except ImportError:
post_install = lambda: None
class my_install(install_data):
def run(self):
install_data.run(self)
post_install()
if __name__ == '__main__':
setup(
...
cmdclass={'install_data': my_install},
...
)
Dans post_setup.py
:
def main():
"""Do here your post-install"""
pass
if __name__ == '__main__':
main()
avec l'idée courante de lancer setup.py
à partir de son répertoire, vous pourrez importer post_setup.py
sinon il lancera une fonction vide.
dans post_setup.py
, la déclaration if __name__ == '__main__':
vous permet de lancer manuellement une post-installation à partir de la ligne de commande.
je pense que la façon la plus facile d'effectuer la post-installation, et de garder les exigences, est de décorer l'appel à setup(...)
:
from setup tools import setup
def _post_install(setup):
def _post_actions():
do_things()
_post_actions()
return setup
setup = _post_install(
setup(
name='NAME',
install_requires=['...
)
)
ce sera setup()
en déclarant setup
. Une fois fait avec l'installation des exigences, il exécutera la fonction _post_install()
, qui exécutera la fonction interne _post_actions()
.
combinant les réponses de @Apalala, @Zulu et @mertyildiran; cela a fonctionné pour moi dans un environnement Python 3.5:
import atexit
import os
import sys
from setuptools import setup
from setuptools.command.install import install
class CustomInstall(install):
def run(self):
def _post_install():
def find_module_path():
for p in sys.path:
if os.path.isdir(p) and my_name in os.listdir(p):
return os.path.join(p, my_name)
install_path = find_module_path()
# Add your post install code here
atexit.register(_post_install)
install.run(self)
setup(
cmdclass={'install': CustomInstall},
...
Cela vous donne également accès au chemin d'installation du paquet install_path
, pour faire de la shell.