9

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?

vvvvv
  • 25,404
  • 19
  • 49
  • 81
Morlock
  • 6,880
  • 16
  • 43
  • 50

4 Answers4

12

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

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • Hi S.Lott Thanks for your advice. I am aware of the three steps you mention (path, executable bit and shebang!). However, using this knowledge, I cannot make the program work, knowing that it must use some of the files in the sub-folder 'data'. Since I currently do not know where the user will put the program, I cannot 'hardcode' the folder's path into the code (which is probable a very bad idea in any case). I'm looking for an installation process that will both make the program file found in the path AND make it possible to point to the data as: './data/this_file.dat'. How should I proceed? – Morlock Dec 15 '11 at 04:23
  • @Morlock: "Since I currently do not know where the user will put the program". That would be a mistake on your part. Since that's your **real** question, please **update** the question to include a description of your **real** problem. Also, please look at the Python documentation some more. All the information you want is actually available. The global variable `__file__` for example, will provide a lot of information. – S.Lott Dec 15 '11 at 10:47
  • Question updated. I think that the real question is emerging as a result of the dialogue with you and FakeRainBrigand. Thank you for your update. I think I have all the options I need now and will read more about the avenues you suggested. – Morlock Dec 15 '11 at 14:06
2

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.

Brigand
  • 84,529
  • 20
  • 165
  • 173
  • I see the logic, but how will it permit me to use the files needed by my program file (under program_folder/data)? I would put the executable under /usr/local/bin, but what about the 'data' folder? Thanks. – Morlock Dec 15 '11 at 04:26
  • Maybe there is a reserved directory for data where I could put the data files and expect them to be there? /usr/share/my_program? Is is a good practice to do that and then hardcode the location of these files in my script, which would be in /usr/local/bin? This sounds too simple to be true :) My concern is to learn of a proper way of doing this for my future programs. – Morlock Dec 15 '11 at 04:45
  • @Morlock, there's really no *correct* place to put them. It's perfectly acceptable to leave them where the user puts them. The [answer here] might help you get at your data folder. – Brigand Dec 15 '11 at 11:29
  • The link (answer here) does not appear to work. I would be interested to see it. – Morlock Dec 15 '11 at 13:44
  • Sorry, try this: http://stackoverflow.com/questions/2259503/how-to-know-the-path-of-the-running-script-in-python – Brigand Dec 15 '11 at 14:16
0

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.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
0

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.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670