[GRASS-dev] Python Scripting

Michael Barton michael.barton at asu.edu
Sat Jul 19 12:17:49 EDT 2008


On Jul 18, 2008, at 11:03 PM, <grass-dev-request at lists.osgeo.org> wrote:

> Date: Fri, 18 Jul 2008 18:20:46 +0100
> From: Glynn Clements <glynn at gclements.plus.com>
> Subject: Re: [GRASS-dev] Python Scripting
> To: "Dan D'Alimonte" <dan at dalimonte.ca>, grass-dev at lists.osgeo.org
> Message-ID: <18560.53486.897323.701173 at cerise.gclements.plus.com>
> Content-Type: text/plain; charset="us-ascii"
>
>
> Glynn Clements wrote:
>
>>> As to existing modules, what about a helper function to access then?
>>>
>>> module.executeModule( name="r.stats", options={ "input":
>>> "elevation.dem,slope,aspect", "fs": ",", "output": "elev.csv"},
>>> flags=["q", "1", "n", "g"] )
>>
>> This idea has occurred to me. Some comments:
>>
>> Pass argument values as Python values, e.g. passing multiple values  
>> as
>> lists, passing numeric types directly, etc, and have the interface
>> convert them to strings. Pass the flags as a single string.
>>
>> module.execute( "r.stats",
>>                options = { "input": ["elevation.dem", "slope",  
>> "aspect"],
>>                            "fs": ",",
>>                            "output": "elev.csv" },
>>                flags = "q1ng" )
>>
>> Provide a lower-level function which simply generates the command to
>> pass to Popen(), for cases where you want to interact with the child
>> process.
>
> I have attached a first draft of such a module, which also includes a
> wrapper function for g.parser (for which an example script is also
> attached).
>
> -- 
> Glynn Clements <glynn at gclements.plus.com>
>
> -------------- next part --------------
> import os
> import os.path
> import sys
> import types
> import subprocess
>
> def _make_val(val):
>    if isinstance(val, types.StringType):
> 	return val
>    if isinstance(val, types.ListType):
> 	return ",".join(map(_make_val, val))
>    if isinstance(val, types.TupleType):
> 	return _make_val(list(val))
>    return str(val)
>
> def make_command(prog, options = [], flags = "", overwrite = False,  
> quiet = False, verbose = False):
>    args = [prog]
>    if overwrite:
> 	args.append("--o")
>    if quiet:
> 	args.append("--q")
>    if verbose:
> 	args.append("--v")
>    if flags:
> 	args.append("-%s" % flags)
>    for opt, val in options.iteritems():
> 	args.append("%s=%s" % (opt, _make_val(val)))
>    return args
>
> def start_command(prog, options = [], flags = "", overwrite = False,  
> quiet = False, verbose = False, **kwargs):
>    args = make_command(prog, options, flags, overwrite, quiet,  
> verbose)
>    return subprocess.Popen(args, **kwargs)
>
> def run_command(*args, **kwargs):
>    ps = start_command(*args, **kwargs)
>    return ps.wait()
>
> def _parse_env():
>    options = {}
>    flags = {}
>    for var, val in os.environ.iteritems():
> 	if var.startswith("GIS_OPT_"):
> 	    opt = var.replace("GIS_OPT_", "", 1).lower()
> 	    options[opt] = val;
> 	if var.startswith("GIS_FLAG_"):
> 	    flg = var.replace("GIS_FLAG_", "", 1).lower()
> 	    flags[flg] = bool(int(val));
>    return (options, flags)
>
> def parser():
>    if not os.getenv("GISBASE"):
>        print >> sys.stderr, "You must be in GRASS GIS to run this  
> program."
>        sys.exit(1)
>
>    if len(sys.argv) > 1 and sys.argv[1] == "@ARGS_PARSED@":
> 	return _parse_env()
>
>    argv = sys.argv[:]
>    name = argv[0]
>    if not os.path.isabs(name):
> 	argv[0] = os.path.normpath(os.path.join(sys.path[0], name))
>
>    os.execvp("g.parser", [name] + argv)
>    raise OSError("error executing g.parser")
> -------------- next part --------------
> #!/usr/bin/env python
>
> # g.parser demo script for python programing
>
> import grass
>
> #%Module
> #%  description: g.parser test script (python)
> #%End
> #%flag
> #%  key: f
> #%  description: a flag
> #%END
> #%option
> #% key: raster
> #% type: string
> #% gisprompt: old,cell,raster
> #% description: raster input map
> #% required : yes
> #%end
> #%option
> #% key: vector
> #% type: string
> #% gisprompt: old,vector,vector
> #% description: vector input map
> #% required : yes
> #%end
> #%option
> #% key: option1
> #% type: string
> #% description: an option
> #% required : no
> #%end
>
> if __name__ == "__main__":
>    (options, flags) = grass.parser()
>
>    print ""
>    if flags['f']:
>        print "Flag -f set"
>    else:
>        print "Flag -f not set"
>
>    #test if parameter present:
>    if options['option1']:
>        print "Value of option1: '%s'" % options['option1']
>
>    print "Value of raster= option: '%s'" % options['raster']
>    print "Value of vector= option: '%s'" % options['vector']

Do you still run a GRASS command as subprocess.call([command...])? Or  
is there another syntax with your wrapper script (e.g., as in the  
module.execute() above)?

Michael



More information about the grass-dev mailing list