Python Package Distribution

March 22nd, 2005 by Patrick Boucher - Viewed 1580 times - Popularity: 5% [?]




I got an e-mail from Phil Barrenger today asking me a few questions and I thought I’d post the answers here because they’d probably be useful to more than Phil. He also got me thinking and I realized I’d made a little mistake packaging my pb.xsi module, I was missing a file in the zip I made for XSIBlog. The zip is fixed and all links are updated. Sorry for the inconvenience.

Now, on with Phil’s questions.

If you develop modules/packages in Python and your script relies on these modules you’ll have to redistribute said modules/packages along with your script. If you downloaded my pb.xsi package and use it in your scripts, you’ll have to redistribute the package if you want to give away your script. As a side note, the aforementioned package wasn’t necessarily meant to be used as is, it was meant to be more of a starting point for your own custom library in your facility.

If you do want to distribute packages there are a few things you should know that might make your life easier…


Python Search Path

When Python searches for a module or a package it goes through the python search path. The search path is composed of the home directory the script was started in, the PYTHONPATH environment variable, standard library directories and finally .pth files. The home directory could be our solution to easily distributing modules with our scripts but because we are running within the XSI environment, the home directory of the currently running interpreter is the directory where you started XSI. You can test this out by running the following code in XSI.

1
2
import os
print os.getcwd()

Marginally helpful.

The search path is accessible through the sys.path list, one path per list element, if you import the standard sys module. This means your script can query the search path and dynamically alter the search path if you want it to. Which could lead us to doing things like…

1
2
import sys
print sys.path

or

1
2
3
4
import sys
if Application.InstallationPath(1) + r"\Data\Scripts" not in sys.path:
	sys.path.insert(0, Application.InstallationPath(1) + r"\Data\Scripts")
from twidel.didum import myVariable

The above code states that if the XSI user’s Scripts directory is not in the search path, add it to the front of the search path. So, distributing a zip that has the following structure:

myScript.py
twidel
    __init__.py
    didum
        __init__.py < - myVariable declared here

If the user unzips this file in his scripts directory and your myScript.py file properly prepends Python's search path as per the above example, your script should find all its modules. You better be using at least a few imports from a custom library for this solution to be viable instead of adding just a few lines of code to the top of your distributed file.

Now this is surely not the most elegant way of doing things and I'd like to hear other people's ideas. Of course you'll also have to riff on the original idea if you've developed a plug-in or if you want the user to put the files in his workgroup or other variants of the situation.

Hope this helps...

Popularity: 5% [?]

2 Responses to “Python Package Distribution”

  1. The .pth file approach is, imho, BY FAR the easiest way to deal with the PYTHONPATH issue. Just drop a text file with a .pth extension into the Python root directory (ie: C:\Python24) that contains the path to the module of your choice, and there you go, you can import directly the scripts in that directory without naming any directory.

    After that, the only thing you need to traverse down subdirectories is to separate directory names with a dot in your import statement:

    import subdirectory1.subdirectory2.myModuleFile

    Wich is the same as, on Windows:

    import \subdirectory1\subdirectory2\myModuleFile.py

    I do have a question though, regarding the __init__.py files. Has anyone here manage to assign subdirectory globals through init files? If I try to create an XSIApplication object or assign a name to the XSI constants in the init file, the modules of this directory do not get them…. so I have to assign them in every module.

    Cheers
    Bernard

  2. I agree that the .pth files are a great way to alter the Python search path, but as someone who is distributing your script to a wide audience, you don”t have control over your user’’s .pth files.

    The idea was to find a way to give a script that relies heavilly on external custom libraries to a non technical user. A user who might not have the expertise (or rights for that matter) to alter his Python path. If that user can”t add .pth files or alter an environment variable due to rights restrictions can we still give him tools that are built on a library with little to no configuration work on his behalf?

    I agree that the way I described above if far from optimal but I haven”t had time to dig any deeper.

Leave a Reply