Interfacing ghpython with python 3.x?

grasshopper
python
rhino5

#1

Hi everybody!
I’m looking for a way to use python 3.x in Gh.

I know of Rhino using IronPython2, which I guess complicates things a little, but I’m thinking there must be a workaround, even if it’s perhaps not super simple.

My preferred solution would be to write the python 3.x code as a separate module or package (could be free of any Rhino/Gh API) and then have the ghpython node provide the script with some input, execute it, retrieve some data and port that data into Rhino objects.

I’ve done similar things writing python 2.7 modules without any issues, but my understanding and experience interfacing between languages is more or less non existent and I couldn’t find anything directly on this particular topic here on the forum or on the web, hence I would be very greatful for any pointers, tips or example or how this could be achieved :slight_smile:

(Its of course all the interesting machine learning modules for 3.x that motivates this question)

All the best!

/J


(Nathan 'jesterKing' Letwory) #2

You may want to check out http://www.food4rhino.com/app/gh-python-remote

Note that in the comments for it are questions about interfacing with Python 3 - essentially no. Unless you are not using any GH/Rhino stuff, in which case GH_CPython might work for you.


(qythium) #3

Depending on what the data being transfered is, and if you don’t mind the significant overhead, you could try using the built-in pickle module to dump and load data from a temporary file that both environments have access to.

I’ve used this in the past for simple things like namedtuples and dictionaries, but it might break down for more complex objects, especially if they depend on the some module’s CPython implementation… vary the protocol argument to see what works :slight_smile:


#4

@nathanletwory
Thanks, that looks like a great tip! I’m not looking to use any of the Rhino/GH API in the module code anyways, I find it to be more clear and modular to just use the GH-python node for formatting the input and output information when possible.

@qythium
Could also work! Without knowing much of the size of the data i’ll be working with, I’m thinking most of the information will never have to be sent between Rhino and the module anyways, so pickle seems like a simple and straight forward solution :slight_smile: thanks

In the end i guess this question comes down to how to interface between two different languages no matter the environment it’s beeing run in. For instance, how does one interface R and Python? Or R and Java for that matter? Surely there must be a better ways to write production code than saving to file, like setting up a simple http-requests api or something and pass json packets back and forth? I’m not (even close to) an software engineer so all this is very new to me :smiley:


#5

Hey again,
So I have been experimenting to see if I can bridge this by having the GHpython node run a separate python process by calling the subprocess module. I can see the terminal blink by, so the process seems to be instantiated, but for some reason I keep on getting an exit code of 2 and no output.

This is what I have in the GHPython node:

args = ' '.join(str(i) for i in ['python', 'py3.py'] + ['test'])
args = args.split()

try:
    print subprocess.check_output(args)
except subprocess.CalledProcessError, e:
    print e, '\n', e.output

and this is the py3.py that Im trying to run:

import sys
if __name__ == '__main__':
    print(sys.argv[1])

just trying to echo whatever the first argument from subprocess.check_output is.

Seems I’m stuck here and can’t find any info about what Im doing wrong. Very thankful for any thoughts or ideas!

Best

Jakob


(qythium) #6

Are you running this on Windows or Mac? Exit code 2 is usually command line syntax error, check if py3.py is on your system path- and if opening a terminal normally and typing in your command works


(Nathan 'jesterKing' Letwory) #7

And python (3) needs to be on your path, of course.


#8

I’m running Windows 10 Enterprise.
When I run python py3.py test in the windows command prompt it prints the return value as expected. I put the .py file in my user folder as it seemd to be on the path already. I also tried putting this in the gh-python node without any success, still exit 2:

import sys
sys.path.append(dir)

I also found this site:
http://www.ironpython.info/index.php?title=The_subprocess_module
claiming that alot of the functionality of the subprocess module is broken in IronPython, but the information is from 2008 so I have a hard time believing it’s still accurate?

As of now python refers to python 2.7 on my machine, so I haven’t really been trying it out for python 3 yet, but I guess the process is the same from the IronPython side anyway and that this just may be changed later?


(qythium) #9

Try using os.chdir() instead of appending to your sys.path, and then print subprocess.check_output(["cd"], shell=True) to make sure you’re spawning the process from the correct directory.


#10

Amazing, it worked! os.chdir() did the trick and now i get the output returned in the python-node from a separarte python 2.7 process. I’ll try with 3.6 and get back with the results.

*EDIT
Seems to work like a charm for python 3.6 as well as long as its in the PATH. os.chdir() instead of sys.path.append() seemed to be key. Many thanks @qythium!

*EDIT
Now, for some reason, sys.path.append() also seems to work fine. Maybe i just had a sloppy path setting or something. Everything I changed was adding python3.6 to the path (was trying 2.7 before so guess it should not matter). Also added .PY to my PATHEXT.