I’m working on a project where I need to send data from a Python script to a Grasshopper definition, trigger its execution, and then retrieve the computed results in JSON format.
I was wondering if this is possible via an HTTP request, using something like Flask or FastAPI in Python. Ideally, Grasshopper would receive the data, process it, and return the results.
Has anyone implemented something like this? Would I need a specific plugin or is there a native way to achieve this?
Any guidance, examples, or recommendations would be greatly appreciated!
Thank you for your previous response. Unfortunately, I had already seen that approach, but my current need is a bit different. My intended workflow is as follows:
Work in Python
Retrieve the necessary data
Find a way to send the generated data from Python to a Grasshopper definition
Process the data inside the Grasshopper definition
Return the computed result back to Python
I have reviewed the tutorials and managed to make Hops read a function hosted on one of my local ports. However, in that case, the workflow follows this sequence:
Grasshopper > Python service (Flask) > Grasshopper
Given my specific case, I am unsure whether Hops can help solve the problem. Do you have any recommendations on how to proceed?
Here’s a Python Notebook I made a while back with an example of how to invoke a Hops definition on Rhino.Compute with input sent from another Python process.
Apologies if this is an over simplification. Grasshopper definitions can be run from the command line, Python can do pretty much anything on the command line using subprocess.run, and it’s easy to write some sort of file from Grasshopper that Python can read.
So can your Grasshopper definitions be adapted slightly, to make it easier to accept the data from a Grasshopper Python component?
Python components in Grasshopper can read environment variables, and read files. You can even spin up an udp or http server within a Grasshopper Python component and send whatever binary data you like to it (I’ve not tested spawning an external thread in Grasshopper, just calling out to external UDP servers in Python). It just needs a bit of work for each Grasshopper definintion to get it from that server component.
The main objective of this post has been achieved, which was to find a way to send data, in my case, from Python to a Grasshopper definition. Thanks to the files provided by @ondrej, I was able to study how to load a .gh definition using the given examples. After some testing, I successfully verified this approach with multiple test definitions before applying it to a real case. However, I will continue researching the topic for scalability, performance, optimization, and potential alternatives as this is just the first step of many.
For now, I would like to share the method I used to work with my own Grasshopper definitions, building upon Ondrej’s contribution:
Review the explanation and test everything in Jupyter Notebook to ensure proper functionality.
Analyze the structure of the .json files to understand their components. Upon reviewing them, we find the keys “algo” and “pointer”, which are essential for loading our Grasshopper definitions:
“algo”: The Grasshopper definition converted to Base64.
“pointer”: The MD5 hash key of the .gh definition.
Prepare the .gh definition to receive inputs via requests.post() and ensure the proper formatting for processing. The same approach applies when returning results to Python.
It took me a considerable amount of time to understand and implement my own .gh definitions, so I am sharing this post in case it helps anyone else facing similar problems.