I have a small program in python that consists in one .py file plus a directory of data files used by the program.
I would like to know the proper way to create an installation procedure for a user with admin rights on Linux so that he can install the program on his system and use it from the command line, with options and parameters. EDIT: The part I am having trouble with is to have the program, once installed, retrieve the data files, contained in a 'data' sub-folder.
Would a setup script that installs the executable program file in /usr/local/bin
and the data folder in /usr/share/my_program/data
be an acceptable solution? Something like:
#!/bin/bash
# Launch with sudo
chmod +x program.py
cp program.py /usr/local/bin
cp -r data /usr/share/my_program
echo Installation complete
Now, in order to do that, I have to assume, in the program, that the data files are going to be in /usr/share/my_program/data
. But I would also leave the user the choice of using the program without installing it. Then I would have to assume that the data are in './data', relative to the executable program file. How should I solve this problem? I can think of a few ways, but my feeling is that I am creating a mess where there should be a clear and correct answer.
Currently, I am considering using a try except clause:
try:
find data from /usr/share/my_program && set path accordingly
except:
set path to the data as './data'
Again, I feel it is a bit convoluted. How would you proceed for the installation?
Many thanks
EDIT: SOLUTION ADOPTED
Based on the answers of this question, and to those in the question suggested by FakeRainBrigand (How to know the path of the running script in Python?), I created an install script that goes like this:
#!/bin/bash
mkdir /usr/share/my_program
chmod +x my_program.py
cp my_program.py /usr/local/bin
cp -r data /usr/share/my_program
echo Installation completed
And added the following code in my program:
if os.path.dirname(__file__) == "/usr/local/bin":
DATA_PATH = "/usr/share/my_program/data"
elif os.path.dirname(__file__) == ".":
DATA_PATH = "./data"
else:
print "You do not have a working installation of my_program"
print "See the installation procedure in the README file"
sys.exit(1)
I then use os.path.join(DATA_PATH, "file-to-reach.txt")
so that the program can reach it's data, found under /usr/share/my_program
.
I would be glad to have comments if a more accepted method is available.
Cheers
To install a package that includes a setup.py file, open a command or terminal window and: cd into the root directory where setup.py is located. Enter: python setup.py install.
Am I wrong that the setup.py method (ie: python setup.py install), is only for installing modules, later to be used from within the interpreter or other scripts?
Yes. You're wrong.
You can install into Python's scripts directory. Keep reading up on all the things setup.py
can do. http://docs.python.org/distutils/setupscript.html#installing-scripts
This is actually very, very simple. And it has nothing to do with Python.
A Python script can be run from anywhere. Linux gives you a wide, wide variety of ways to make an executable file (/path/to/my_program.py
) runnable.
All of those wide, wide variety of ways have three things in common. Three thing that are central to Linux and has nothing to do with Python at all.
The file must be on the user's PATH
.
The file must have "execute" privilege (chmod +x ...
).
The file must begin with #!/usr/bin/env python
.
How do make this happen?
For #1.
You can check the PATH and put the file in any of the directories on the PATH. There are lots of standard choices for this. /usr/local/bin
, for example.
You can modify the user's PATH to include some new directory. /path/to
, for example, so that /path/to/my_program.py
can be found.
For #2. You execute the appropriate chmod +x
.
For #3. You write the appropriate line of code.
For more information read up on "Linux Shell". All "shell" programs have the same three features. bash
. csh
, python
, perl
, etc., etc., etc.
retrieve the data files, contained in a 'data' sub-folder, while refering to them as
./data/this_file.dat
, for example.
That would be a poor design.
Linux (outside Python) provides a lot of ways to find useful data files.
Install them in a known location with a known path. /usr/local/share
comes to mind. This may not be the best location, but it's reasonably popular.
Use environment variables. MYAPP_HOME
, for example, can be set to the location of the file. The you can use os.path.join( os.environ['MYAPP_HOME'], 'data', 'this_file.dat' )
Very popular.
Use the __file__
variable to find out where your script is located. Then use os.path
to locate the directory and assemble the data path with os.path.join( this_directory, 'data', 'this_file.dat' )
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