<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jul 19, 2017 at 1:42 AM, Pietro <span dir="ltr"><<a href="mailto:peter.zamb@gmail.com" target="_blank">peter.zamb@gmail.com</a>></span> wrote:<br><div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-">On Mon, Jul 17, 2017 at 5:36 PM, Vaclav Petras <span dir="ltr"><<a href="mailto:wenzeslaus@gmail.com" target="_blank">wenzeslaus@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-m_-5649327697261403299gmail-">On Mon, Jul 17, 2017 at 12:36 AM, Pietro <span dir="ltr"><<a href="mailto:peter.zamb@gmail.com" target="_blank">peter.zamb@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div class="gmail_extra"><br><div class="gmail_quote"><span class="gmail-m_-5649327697261403299gmail-m_3599744528868547718gmail-">On Fri, Jul 14, 2017 at 6:00 PM, Vaclav Petras <span dir="ltr"><<a href="mailto:wenzeslaus@gmail.com" target="_blank">wenzeslaus@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>This is exactly what I had in my mind when doing the last major changes in the grass.py file. <br></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto">I generally like the layout you suggested. It seems to me that choosing a good name for the whole module will be a bit tricky. </div></blockquote></span><div><br>This is intended as a proof of concept to see the feasibility.<br></div><div>I've try to found a better name but didn't come up to my mind...<br></div><div>Perhaps: <span style="font-family:monospace,monospace">session</span> instead of <span style="font-family:monospace,monospace">init</span>?<br><br></div><div>My final objective is to be able to do something like:<br></div></div></div></div></div></blockquote><div><br></div></span><div>That makes sense. In fact, that's very similar to a file I drafted some time ago splitting the data initialization and runtime in grass.script.setup and adding Session (see the attached file). Another example, for a different case, is here:<br><br><a href="https://github.com/wenzeslaus/g.remote/blob/master/grasssession.py" target="_blank">https://github.com/wenzeslaus/<wbr>g.remote/blob/master/grasssess<wbr>ion.py</a></div></div></div></div></blockquote><div><br></div></span><div>Nice module, I was not aware of it!<br></div><div>However I think that the purpose is slightly different. The grassession aims is to generate the session remotely, here I would like to setup a local session. It is true that I should be able to just connect through ssh to the localhost... but it seems to me not the right way.</div></div></div></div></blockquote><div><br></div><div>Sure, the code is for use remote session on another computer, although by switching the backend you can use the API for local session (without any ssh to localhost):<br></div><div><br><a href="https://github.com/wenzeslaus/g.remote/blob/master/localsession.py">https://github.com/wenzeslaus/g.remote/blob/master/localsession.py</a><br><br></div><div>What I'm bring up here is the idea of a Session API which works the same for local session, remote session, or multiple sessions (in one script).<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> So I've sketch a possible implementation just to see how it could work, see:<br><br><a href="https://git.osgeo.org/gogs/zarch/grass/commit/b9cb69a1d7381924b0c2229ba43f21b1b7473c72" target="_blank">https://git.osgeo.org/gogs/<wbr>zarch/grass/commit/<wbr>b9cb69a1d7381924b0c2229ba43f21<wbr>b1b7473c72</a><br><br></div></div></div></div></blockquote><div><br></div><div>Looks nice and clean. The difference to the above is that it does not contain API for actually executing anything which removes the dependency problems I mentioned earlier. This is probably much more fitting to the current session as opposed to the remote (or generally "other") session as used in g.remote. In other words, we have two different concepts for a Session object (API): SessionA which sets the global state and thus sets up a current session and SessionB which sets up a session which is remote or local (but does touch the global state, i.e. the current session). SessionA does not have any extra functions and all is executed through standard (current) APIs while SessionB needs to provide all (or at least some) functions for execution of modules or code (e.g. g.remote executes scripts).<br><br></div><div>Besides the fact that SessionA and SessionB have very different APIs and behavior, my concern is that I think we should consider (and possibly cover) the use case of parallel processing in different mapsets or parallel rendering. SessionA is not good for this. SessionB is.<br><br></div><div>Another concern is the usage of context manager. It makes sense. It is a resource, you connect, you open. But the state which is changes is global. Is that expected from context manager? I don't know, I need to read the PEP.<br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-m_-5649327697261403299gmail-"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div class="gmail_extra"><div class="gmail_quote"><div><span style="font-family:monospace,monospace">from grass.init import Session<br><br></span></div><span class="gmail-"><div><span style="font-family:monospace,monospace"># with statement<br></span></div><div><span style="font-family:monospace,monospace">with Session('mygisdbase/location/m<wbr>apset') as session:<br></span></div><div><span style="font-family:monospace,monospace">    # do my stuff here<br>```</span><br></div><div> <br></div></span></div></div></div></div></blockquote><div><br></div></span><span class="gmail-"><div>Unfortunately, here is where the trouble begins. The above leads to the following:<br><br></div><div>with Session as session:<br></div><div>    session.run_command(...)<br><br></div><div>which fits with API which already exists for Ruby:<br><br><a href="https://github.com/jgoizueta/grassgis/" target="_blank">https://github.com/jgoizueta/g<wbr>rassgis/</a><br></div><div>






<p>
GrassGis.session configuration do+<br>    <a href="http://r.info" target="_blank">r.info</a> 'slope'<br>    g.region '-p'<br>
end
</p>



</div><div>The trouble is that session (at least in Python) needs to depend on the rest of the library because it is the interface for the rest (on demand imports may help here).<br></div></span></div></div></div></blockquote><div><br></div><div>Sorry I'm not sure that I get your point here, what do you mean?<br>The following code is running at the moment on my machine:<br><br></div><div><span style="font-family:monospace,monospace"><span class="gmail-">```python<br>import os<br>import sys<br><br></span>MAPSET = '/home/pietro/docdat/gis/nc_<wbr>basic_spm_grass7/user1/'<br>GISBASE = '/home/pietro/docdat/src/gis/<wbr>ggrass/dist.x86_64-pc-linux-<wbr>gnu/'<br><br></span></div><div><span style="font-family:monospace,monospace"># set the path<br></span></div><div><span style="font-family:monospace,monospace">sys.path.append(os.path.join(<wbr>os.environ.get('GISBASE', GISBASE),<br>                             'etc', 'python'))<br><br></span></div><div><span style="font-family:monospace,monospace"># import the python GRASS libraries<br></span></div><div><span style="font-family:monospace,monospace">from grass.script.core import run_command<br>from session import Session<br><br><br>with Session(MAPSET) as session:<br>    run_command('r.slope.aspect', elevation='elevation',<br>                slope='slope', aspect='aspect',<br>                overwrite=True)</span><span style="font-family:monospace,monospace"><br>```</span><br></div><span class="gmail-"><div><br></div></span></div></div></div></blockquote><div><br></div><div>My concern is just another concern about the context manager. Is is OK that it is actually not used in the with block? Again, that's something PEP hopefully answers.<br><br></div><div>Whatever would be the default usage, I can see how it could be used. Here is an example for the use case when we are currently passing the env parameter (like the parallel processing mentioned above):<br></div><div><br><span style="font-family:monospace,monospace">```<br>with Session(MAPSET) as session:<br>    run_command('r.slope.aspect', elevation='elevation',<br>                slope='slope', aspect='aspect',<br>                overwrite=True, env=session.env)<br>```<br></span><span style="font-family:monospace,monospace"></span></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>So perhaps having grass.init or grass.setup with the low level functions and then a separate grass.session with a nice interface which may depend on all other modules may be a better way. (Although having each function from the library as a method of Session calls for more thinking about grass.session.Session.</div></div></div></div></blockquote><div><br></div></span><div>I was thinking to add this Session class definition inside init/session.py to then try to refactor the main function in parser.py:<br><br><a href="https://git.osgeo.org/gogs/zarch/grass/src/grass_session/lib/python/init/parser.py#L189" target="_blank">https://git.osgeo.org/gogs/<wbr>zarch/grass/src/grass_session/<wbr>lib/python/init/parser.py#L189</a><br><br></div><div>to start a session and then execute all the rest of the functions to start/use the grass shell/gui.<br></div><span class="gmail-"><div> <br></div></span></div></div></div></blockquote><div><br></div><div>I'm not sure what are the changes you plan. What I can say now is that I suggest to not use the name parser.py as it means something very specific in GRASS. I'm also not sure if main() of lib/init/grass.py should be part of the library (it seems to me actually impossible as it should be on the executable path rather than a library path).<br></div></div></div></div>