Proper installation script for a small Python program (Not module) under Linux

Question:

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?

Asked By: Morlock

||

Answers:

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.

  1. The file must be on the user’s PATH.

  2. The file must have “execute” privilege (chmod +x ...).

  3. 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.

  1. 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.

  2. 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.

  3. 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' )

Answered By: S.Lott

If you have no external dependencies, such as databases or settings that need to be configured, a simple setup.sh script should do.

DIR=`pwd`
NAME=my_app.py
echo "#!/usr/bin/env sh 
python $DIR/my_app.py" > /usr/sbin/$NAME
chmod a+x /usr/sbin/$NAME

It can get more complicated depending on your needs.

Answered By: Brigand

You could create an executable zip file that contains your script and data files that it uses. An installation just need to put this file somewhere in $PATH and make it executable: chmod +x my-program.

python: can executable zip files include data files?

If you create an appropriate setup.py that specifies how to install your data files and the script then there are many more options to install the program e.g.,

$ pip install --user http://example.com/your-program.tar.gz

where pip can be installed via a system packager, your-program.tar.gz you could create using python setup.py sdist.

Answered By: jfs

Based on the answers of this question, and to those in the question suggested by FakeRainBrigand (How can I 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.


This answer was posted as an edit to the question Proper installation script for a small Python program (Not module) under Linux by the OP Morlock under CC BY-SA 3.0.

Answered By: vvvvv
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.