I have a package awesomepkg
with setup.py
. I'd like to install a binary executable awesometool
to the command line along with the package itself when users run pip install awesomepkg
. I have compiled different OS versions for awesometool
, which lives in a bin/
folder beside setup.py
.
However, I can't find a good way to configure setup.py
. I have attempted the following:
Use the scripts=[]
keyword in setup()
. Unfortunately, the "executable" must be a python script.
So I try to wrap the binary in a python script using os.system('bin/awesometool')
to delegate. It also fails because the wrapper script is copied somewhere else by pip, so it doesn't know where the relative path bin/awesometool
is.
Another potential solution is the data_files
keyword. However, for some reason the data files are not copied over to site_packages
installation dir, even though running python setup.py bdist_wheel
says they have been copied.
Reference: https://docs.python.org/3/distutils/setupscript.html
When it comes to automating the installation of Python packages, you can create a Python script that runs pip as a subprocess with just a few lines of code: The package, as well as any requirements will be installed.
Use of a Python script to run pip to install a package is not supported by the Python Packaging Authority (PyPA) for the following reason: Pip is not thread-safe, and is intended to be run as a single process. When run as a thread from within a Python script, pip may affect non-pip code with unexpected results.
How to Run Pip as a SubProcess When it comes to automating the installation of Python packages, you can create a Python script that runs pip as a subprocess with just a few lines of code: import sys import subprocess # implement pip as a subprocess: subprocess.check_call (
Step 1: Go to the directory in which your python script is present for example assume if we take this code in our directory. Step 2: In this directory run the following command that will create a requirement file.
I just ran into this issue myself. My solution was three-fold.
I added the program, e.g. awesometool
, to my package structure so I could add it via the package_data
keyword:
package_data={'awesomepkg': ['awesometool']}
.
This causes it to actually be copied into the same folder as the main init.py during installation.
I made a python script similar to your step 2. However, instead of the relative path, I first import awesomepkg
and use awesomepkg.__path__
to get the absolute path to the installation folder for the package. This would look like:
import awesomepkg
import subprocess as sp
import sys
path = awesomepkg.__path__[0]
command = path + "/awesometool"
sp.call([command] + sys.argv)
I also used subprocess instead of system, but the result should be the same.
I added this script to the scripts
keyword of setup()
To add on to Nick Porubsky's answer:
chmod +x
An example of this can be found here. https://github.com/HousekeepLtd/pywkher/commit/0bad81240f16479550e2b1bf2c1185a20d3cee29
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With