Post-install script with Python setuptools Post-install script with Python setuptools python python

Post-install script with Python setuptools


Note: The solution below only works when installing a source distribution zip or tarball, or installing in editable mode from a source tree. It will not work when installing from a binary wheel (.whl)


This solution is more transparent:

You will make a few additions to setup.py and there is no need for an extra file.

Also you need to consider two different post-installations; one for development/editable mode and the other one for install mode.

Add these two classes that includes your post-install script to setup.py:

from setuptools import setupfrom setuptools.command.develop import developfrom setuptools.command.install import installclass PostDevelopCommand(develop):    """Post-installation for development mode."""    def run(self):        develop.run(self)        # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTIONclass PostInstallCommand(install):    """Post-installation for installation mode."""    def run(self):        install.run(self)        # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION

and insert cmdclass argument to setup() function in setup.py:

setup(    ...    cmdclass={        'develop': PostDevelopCommand,        'install': PostInstallCommand,    },    ...)

You can even call shell commands during installation, like in this example which does pre-installation preparation:

from setuptools import setupfrom setuptools.command.develop import developfrom setuptools.command.install import installfrom subprocess import check_callclass PreDevelopCommand(develop):    """Pre-installation for development mode."""    def run(self):        check_call("apt-get install this-package".split())        develop.run(self)class PreInstallCommand(install):    """Pre-installation for installation mode."""    def run(self):        check_call("apt-get install this-package".split())        install.run(self)setup(    ...

P.S. there are no any pre-install entry points available on setuptools. Read this discussion if you are wondering why there is none.


Note: The solution below only works when installing a source distribution zip or tarball, or installing in editable mode from a source tree. It will not work when installing from a binary wheel (.whl)


This is the only strategy that has worked for me when the post-install script requires that the package dependencies have already been installed:

import atexitfrom setuptools.command.install import installdef _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},


Note: The solution below only works when installing a source distribution zip or tarball, or installing in editable mode from a source tree. It will not work when installing from a binary wheel (.whl)


A solution could be to include a post_setup.py in setup.py's directory. post_setup.py will contain a function which does the post-install and setup.py will only import and launch it at the appropriate time.

In setup.py:

from distutils.core import setupfrom distutils.command.install_data import install_datatry:    from post_setup import main as post_installexcept ImportError:    post_install = lambda: Noneclass my_install(install_data):    def run(self):        install_data.run(self)        post_install()if __name__ == '__main__':    setup(        ...        cmdclass={'install_data': my_install},        ...    )

In post_setup.py:

def main():    """Do here your post-install"""    passif __name__ == '__main__':    main()

With the common idea of launching setup.py from its directory, you will be able to import post_setup.py else it will launch an empty function.

In post_setup.py, the if __name__ == '__main__': statement allows you to manually launch post-install from command line.