Changeset 65346


Ignore:
Timestamp:
May 31, 2015, 9:04:56 PM (9 years ago)
Author:
wenzeslaus
Message:

pythonlib: add example and addons to setup.init function

Motivation: http://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&diff=next&oldid=20818

Adding also an example which is simplified but fully sufficient (and tested for extreme cases) version of the first example on the wiki page:
http://grasswiki.osgeo.org/w/index.php?title=Working_with_GRASS_without_starting_it_explicitly&oldid=21422

Documentation should be kept with API. There is a too many misteries related to this topic. More improvementes could be done with lib/init/grass.py functions generalized and moved to lib/python/script/setup.py (see TODOs in the code).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • grass/trunk/lib/python/script/setup.py

    r65345 r65346  
    1 """!@package grass.script.setup
     1"""Setup and initialization functions
    22
    3 @brief GRASS Python scripting module (setup)
     3Function can be used in Python scripts to setup a GRASS environment
     4without starting an actual GRASS session.
    45
    5 Setup functions to be used in Python scripts.
     6Usage::
    67
    7 Usage:
     8    import os
     9    import sys
     10    import subprocess
    811
    9 @code
    10 from grass.script import setup as grass
     12    # define GRASS Database
     13    # add your path to grassdata (GRASS GIS database) directory
     14    gisdb = os.path.join(os.path.expanduser("~"), "grassdata")
     15    # the following path is the default path on MS Windows
     16    # gisdb = os.path.join(os.path.expanduser("~"), "Documents/grassdata")
    1117
    12 grass.init()
    13 ...
    14 @endcode
     18    # specify (existing) Location and Mapset
     19    location = "nc_spm_08"
     20    mapset = "user1"
     21
     22    # path to the GRASS GIS launch script
     23    # we assume that the GRASS GIS start script is available and on PATH
     24    # query GRASS itself for its GISBASE
     25    # (with fixes for specific platforms)
     26    # needs to be edited by the user
     27    grass7bin = 'grass70'
     28    if sys.platform.startswith('win'):
     29        # MS Windows
     30        grass7bin = r'C:\OSGeo4W\bin\grass70.bat'
     31        # uncomment when using standalone WinGRASS installer
     32        # grass7bin = r'C:\Program Files (x86)\GRASS GIS 7.0.0\grass70.bat'
     33        # this can be avoided if GRASS executable is added to PATH
     34    elif sys.platform == 'darwin':
     35        # Mac OS X
     36        # TODO: this have to be checked, maybe unix way is good enough
     37        grass7bin = '/Applications/GRASS/GRASS-7.0.app/'
     38
     39    # query GRASS GIS itself for its GISBASE
     40    startcmd = [grass7bin, '--config', 'path']
     41    try:
     42        p = subprocess.Popen(startcmd, shell=False,
     43                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     44        out, err = p.communicate()
     45    except OSError as error:
     46        sys.exit("ERROR: Cannot find GRASS GIS start script"
     47                 " {cmd}: {error}".format(cmd=startcmd[0], error=error))
     48    if p.returncode != 0:
     49        sys.exit("ERROR: Issues running GRASS GIS start script"
     50                 " {cmd}:\n{error}"
     51                 .format(cmd=' '.join(startcmd), error=err))
     52    gisbase = out.strip('\n\r')
     53
     54    # set GISBASE environment variable
     55    os.environ['GISBASE'] = gisbase
     56
     57    # define GRASS-Python environment
     58    grass_pydir = os.path.join(gisbase, "etc", "python")
     59    sys.path.append(grass_pydir)
     60
     61    # import (some) GRASS Python bindings
     62    import grass.script as gscript
     63
     64    # launch session
     65    rcfile = gscript.setup.init(gisbase, gisdb, location, mapset)
     66
     67    # example calls
     68    gscript.message('Current GRASS GIS 7 environment:')
     69    print gscript.gisenv()
     70
     71    gscript.message('Available raster maps:')
     72    for rast in gscript.list_strings(type='raster'):
     73        print rast
     74
     75    gscript.message('Available vector maps:')
     76    for vect in gscript.list_strings(type='vector'):
     77        print vect
     78
     79    # delete the rcfile
     80    os.remove(rcfile)
     81
    1582
    1683(C) 2010-2012 by the GRASS Development Team
     
    2087
    2188@author Martin Landa <landa.martin gmail.com>
     89@author Vaclav Petras <wenzeslaus gmail.com>
    2290"""
     91
     92# TODO: this should share code from lib/init/grass.py
     93# perhaps grass.py can import without much trouble once GISBASE
     94# is known, this would allow moving things from there, here
     95# then this could even do locking
    2396
    2497import os
     
    28101
    29102def write_gisrc(dbase, location, mapset):
    30     """Write the gisrc file and return the gisrc path."""
     103    """Write the ``gisrc`` file and return its path."""
    31104    fd, gisrc = tmpfile.mkstemp()
    32105    os.write(fd, "GISDBASE: %s\n" % dbase)
     
    38111
    39112def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
    40     """!Initialize system variables to run scripts without starting
    41     GRASS explicitly.
     113    """Initialize system variables to run GRASS modules
    42114
    43     User is resposible to delete gisrc file.
     115    This function is for running GRASS GIS without starting it
     116    explicitly. No GRASS modules shall be called before call of this
     117    function but any module or user script can be called afterwards
     118    as if it would be called in an actual GRASS session. GRASS Python
     119    libraries are usable as well in general but the ones using
     120    C libraries through ``ctypes`` are not (which is caused by
     121    library path not being updated for the current process
     122    which is a common operating system limitation).
    44123
    45     @param gisbase path to GRASS installation
    46     @param dbase   path to GRASS database (default: '')
    47     @param location location name (default: 'demolocation')
    48     @param mapset   mapset within given location (default: 'PERMANENT')
    49     @return path to gisrc file
     124    To create a (fake) GRASS session a ``gisrc`` file is created.
     125    Caller is resposible for deleting the ``gisrc`` file.
     126
     127    Basic usage::
     128
     129        # ... setup GISBASE and PYTHON path
     130        grass.script as gscript
     131        gisrc = gscript.setup.init("/usr/lib/grass64",
     132                                   "/home/john/grassdata",
     133                                   "nc_spm_08", "user1")
     134        # ... use GRASS modules
     135        os.remove(gisrc)
     136
     137    :param gisbase: path to GRASS installation
     138    :param dbase: path to GRASS database (default: '')
     139    :param location: location name (default: 'demolocation')
     140    :param mapset: mapset within given location (default: 'PERMANENT')
     141    :returns: path to ``gisrc`` file (to be deleted later)
    50142    """
     143    # TODO: why we don't set GISBASE?
     144    mswin = sys.platform.startswith('win')
    51145    # define PATH
    52146    os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'bin')
    53147    os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'scripts')
    54     if sys.platform.startswith('win'):  # added for winGRASS
     148    if mswin:  # added for winGRASS
    55149        os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'extrabin')
     150
     151    # add addons to the PATH
     152    # copied and simplified from lib/init/grass.py
     153    if mswin:
     154        config_dirname = "GRASS7"
     155        config_dir = os.path.join(os.getenv('APPDATA'), config_dirname)
     156    else:
     157        config_dirname = ".grass7"
     158        config_dir = os.path.join(os.getenv('HOME'), config_dirname)
     159    addon_base = os.path.join(config_dir, 'addons')
     160    os.environ['GRASS_ADDON_BASE'] = addon_base
     161    if not mswin:
     162        os.environ['PATH'] += os.pathsep + os.path.join(addon_base, 'scripts')
    56163
    57164    # define LD_LIBRARY_PATH
     
    59166        os.environ['@LD_LIBRARY_PATH_VAR@'] = ''
    60167    os.environ['@LD_LIBRARY_PATH_VAR@'] += os.pathsep + os.path.join(gisbase, 'lib')
    61    
     168
    62169    os.environ['GIS_LOCK'] = str(os.getpid())
    63170
    64171    # Set PYTHONPATH to find GRASS Python modules
     172    # TODO: isn't this useless? user already imported this somehow
    65173    path = os.getenv('PYTHONPATH')
    66174    etcpy = os.path.join(gisbase, 'etc', 'python')
     
    71179    os.environ['PYTHONPATH'] = path
    72180
     181    # TODO: isn't this contra-productive? may fail soon since we cannot
     182    # write to the installation (applies also to defaults for Location
     183    # and mapset) I don't see what would be the use case here.
    73184    if not dbase:
    74185        dbase = gisbase
Note: See TracChangeset for help on using the changeset viewer.