I have published a PyPI package which requires some additional Apt packages and so I have a setup.sh in my Github repository which I want to execute along with the installation process of pip install mypackage (i.e, whenever a user runs pip install mypackage it should run the shell script during the process of installation.)
I made my setup.py to use the cmdclass parameter like this
from setuptools import setup, find_packages
from setuptools.command.install import install
import subprocess
import codecs
import os
class CustomInstall(install):
def run(self):
subprocess.check_call("bash setup.sh", shell=True)
install.run(self)
with open('requirements.txt') as f:
requirements = f.read().splitlines()
setup(
...
cmdclass={'install': CustomInstall}, install_requires=requirements,
...
)
When I normally build it with python setup.py sdist bdist_wheel the Custominstall class runs fine but during pip installation it ignores the Custominstall class.
Finally I found this stackoverflow thread from where I learnt that I only need to run python setup.py sdist which I did and got a tar.gz file in the dist folder but when I go to install that tar.gz file with pip install, I am getting
with open('requirements.txt') as f:
^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'requirements.txt'
What am I doing wrong? Is the path not correct? The requirements file is in my repository's parent folder (not inside any other folder)
The reason why this is happening is because your
setup.pydepends onrequirements.txtbut you're not packagingrequirements.txtin your distribution. If you open your.tar.gz, you won't find yourrequirements.txtfile. To fix this, create aMANIFEST.infile with the contents:And add
include_package_data=Trueto yoursetupcall.You'll need to add any other non-python files you want to include in your
.tar.gzdistribution, such as yoursetup.shscript as well.When you build your source distribution with these changes, you'll see that
requirements.txtis now included in the contents of your build distribution.Alternatively, you can also use the
package_datakeyword insetupfor this (or[options.package_data]insetup.cfg). See: this link for more in depth explanation.Generally speaking though, it's not a good idea to run shell scripts or install system packages as part of your
setup.py. It will make your package harder to use, not easier.If your package depends on Python dependencies use
install_requiresinstead.