Sunday, 4 September 2016

GRASS 7 environment setup for Python


I would like to use some GRASS functionality from a Python programme. With GRASS 6 this required the set up of various environment variables, as detailed in the GRASS Wiki.


I am trying a similar setup with GRASS 7, as in this example:



import os

os.environ['LC_ALL'] = "en_GB.UTF-8"
os.environ['GISBASE'] = "/usr/lib/grass70/"
os.environ['PATH'] = "$PATH:/usr/bin:$GISBASE/bin:$GISBASE/scripts"
os.environ['LD_LIBRARY_PATH'] = "$LD_LIBRARY_PATH:$GISBASE/lib"
# for parallel session management, we use process ID (PID) as lock file number:
os.environ['GIS_LOCK'] = "$$"
# path to GRASS settings file
os.environ['GISRC'] = "$HOME/.grass7"

os.environ['PYTHONPATH'] = "$PYTHONPATH:$GISBASE/etc/python"

import grass.script as grass
env = grass.gisenv()
print env
#List all environment variables
for key, value in os.environ.items(): print key, value
#Print region extent
r = grass.read_command("g.region", flags='p' )
print r


But the end result is an ImportError:


Traceback (most recent call last):
File "grass_test.py", line 13, in
import grass.script as grass
ImportError: No module named grass.script

The basic sanity check shows the script library in the expected folder:


$ ls -la /usr/lib/grass70/etc/python/grass
total 44

drwxr-xr-x 9 root root 4096 Mai 3 08:44 .
drwxr-xr-x 3 root root 4096 Jan 7 08:16 ..
drwxr-xr-x 2 root root 4096 Mai 3 08:44 exceptions
drwxr-xr-x 2 root root 4096 Mai 3 08:44 imaging
-rw-r--r-- 1 root root 151 Mai 1 21:46 __init__.py
-rw-r--r-- 1 root root 363 Mai 3 08:44 __init__.pyc
drwxr-xr-x 2 root root 4096 Mai 3 08:44 lib
drwxr-xr-x 2 root root 4096 Mai 3 08:44 pydispatch
drwxr-xr-x 9 root root 4096 Mai 3 08:44 pygrass
drwxr-xr-x 2 root root 4096 Mai 3 08:44 script

drwxr-xr-x 2 root root 4096 Mai 3 08:44 temporal

What else must be added to this environment setup?


Update: I tried the setup suggested by Gene, but it produces the same ImportError exception:


import os

os.environ['GISBASE'] = "/usr/lib/grass70/"
os.environ['PYTHONPATH'] = "${PYTHONPATH}:$GISBASE/etc/python/"
os.environ['LD_LIBRARY_PATH'] = "$LD_LIBRARY_PATH:$GISBASE/lib"
os.environ['GIS_LOCK'] = "$$"

os.environ['GISRC'] = "$HOME/.grass7/rc"

import grass.script as grass

Answer



Once a python script is running, changes to environment variables are no longer effective. They are set up right before runtime and the interpretor will not update them afterwards. PYTHONPATH can be updated using the method sys.path.append() and that is all.


A workaround is to re-execute the script after setting up the environment. This way the interpreter reloads the environment before starting up the script the second time:


import os, sys

if 'LD_LIBRARY_PATH' not in os.environ:
os.environ['GISBASE'] = "/usr/lib/grass70"

sys.path.append(os.environ['GISBASE'] + "/etc/python/")
os.environ["LD_LIBRARY_PATH"] = os.environ['GISBASE'] + "/lib"
os.environ['GIS_LOCK'] = "$$"
os.environ['GISRC'] = os.environ["HOME"] + "/.grass7/rc"
try:
os.execv(sys.argv[0], sys.argv)
except Exception, exc:
print 'Failed re-exec:', exc
sys.exit(1)


import grass.script as grass

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...