Rhino Compute AWS Server

Hi everyone,

I am trying to run a python script which uses grasshopper scripts to create some Rhino Geometry via compute. The problem is, when I run locally it works however, my company has set up an AWS server that I want to run compute off of but when I use that url and apikey it doesnt work.

This is how I’m setting the URL and Api key, assume I have set the apikey correct (left it blank for now)

compute_url = "http://ec2-instance-url/
compute_rhino3d.Util.url = compute_url
compute_rhino3d.Util.apiKey = ""

This is how I’m sending the post request.

res = requests.post(compute_url + "grasshopper", json=payload)

Like I said when using localhost it works perfectly fine in this format.

Thanks

Don’t you need an api key?

Ahem.

1 Like

I have left it blank for security reasons, which is why I said to assume it was set correctly in my script.

Are you sure you are using the correct port? In a production environment this can be 80 or 443, depending on whether you use ssl. But also the default port of rhino.compute can be 8080, or whatever you want if you use custom settings.

Are you sure that your iis allows incoming connections?

The rhino.compute logs from your server would tell us much more about your problem.


Get requests seem to be working fine however post requests seem to not be working.


compute_url = "http://3.104.37.217:80/"
compute_rhino3d.Util.url = compute_url
compute_rhino3d.Util.authToken = ""
compute_rhino3d.Util.apiKey = ''

headers = {
    "Authorization":"Bearer" + compute_rhino3d.Util.authToken,
    "RhinoComputeKey": ""
}

class __Rhino3dmEncoder(json.JSONEncoder):
    def default(self, o):
        if hasattr(o, "Encode"):
            return o.Encode()
        return json.JSONEncoder.default(self, o)

    gh_admin = open(r"./gh_scripts/admin.ghx", mode="r",
                    encoding="utf-8-sig").read()
    gh_admin_bytes = gh_admin.encode("utf-8")
    gh_admin_encoded = base64.b64encode(gh_admin_bytes)
    gh_admin_decoded = gh_admin_encoded.decode("utf-8")

    all_points = []

    admin_curves = []
    suburb_names = []
    while True:
        admin_response = requests.get(adminboundaries_url, params=params)
        if admin_response.status_code == 200 and admin_response.json():
            admin_data = json.loads(admin_response.text)
            if "features" in admin_data:
                for feature in admin_data["features"]:
                    suburb_name = feature['attributes']['suburbname']
                    geometry = feature["geometry"]
                    for ring in geometry["rings"]:
                        points = []
                        for coord in ring:
                            point = rh.Point3d(coord[0], coord[1], 0)
                            points.append(point)
                            all_points.append(point)
                        polyline = rh.Polyline(points)
                        curve = polyline.ToNurbsCurve()
                        admin_curves.append(curve)
                        suburb_names.append(suburb_name)
                break  # exit the loop if data is found
            else:
                time.sleep(0)
        else:
            # wait for some time before retrying
            time.sleep(0)

    maximum_suburb_num = len(suburb_names) - 1

    suburb_name_to_index = {name: i for i,
                            name in enumerate(set(suburb_names))}
    suburb_indices = list(suburb_name_to_index.values())

    curves_to_include = admin_curves

    # serialize curves
    serialized_curves = []
    for curve in curves_to_include:
        serialized_curve = json.dumps(curve, cls=__Rhino3dmEncoder)
        serialized_curves.append(serialized_curve)

    # create list of dictionaries for each curve
    curves_list = []
    for i, curve in enumerate(serialized_curves):
        curves_list.append(
            {
                "ParamName": "Curves",
                "InnerTree": {
                    f"{{ {i}; }}": [
                        {
                            "type": "Rhino.Geometry.Curve",
                            "data": curve
                        }
                    ]
                }
            }
        )

    max_dict = {
        "ParamName": "Max",
        "InnerTree": {
            "{ 0; }": [
                {
                    "type": "System.Int32",
                    "data": maximum_suburb_num
                }
            ]
        }
    }

    suburb_dicts = []
    for i, suburb_name in enumerate(suburb_names):
        suburb_index = suburb_indices[i]
        suburb_dict = {
            "ParamName": "Numb",
            "InnerTree": {
                f"{{ {i};0 }}": [
                    {
                        "type": "System.Int32",
                        "data": suburb_index
                    }
                ]
            }
        }
        suburb_dicts.append(suburb_dict)

    # update geo_payload with list of curves, point, and string inputs
    geo_payload = {
        "algo": gh_admin_decoded,
        "pointer": None,
        "values": curves_list + [max_dict]
    }

    for i, curve in enumerate(curves_list):
        payload = copy.deepcopy(geo_payload)
        payload["values"].append(curve)
        payload["values"].append(suburb_dicts[i])
        payload["values"].append(max_dict)
        res = requests.post(compute_url + "grasshopper", json=payload, headers=headers)
        response_object = json.loads(res.content)['values']
        for val in response_object:
            paramName = val['ParamName']
            innerTree = val['InnerTree']
            for key, innerVals in innerTree.items():
                for innerVal in innerVals:
                    if 'data' in innerVal:
                        data = json.loads(innerVal['data'])
                        geo = rh.CommonObject.Decode(data)
                        att = rh.ObjectAttributes()
                        att.SetUserString("Suburb Name", str(suburb_names[i]))
                        att.LayerIndex = admin_layerIndex
                        model.Objects.AddMesh(geo, att)

model.Write('C:/Users/RivinduB/Desktop/output.3dm')

You should look in the logs of your ec2 instance for the backend. That’ll give you more info on where the problem is happening, and potentially point you to why.

If you haven’t sorted this out, I happened to have a similar situation. My Rhino.Compute runs perfectly on my local server but refused to work once it’s on the EC2 instance. The problem I found later was that my MongoDB IP wasn’t whitelisted to access the EC2 instance. I thought it might be something similar to yours, perhaps your laptop IP is not whitelisted to access the AWS server or something like that? Might be worth checking the security group.

Hi @yangallen3,

Thanks for the message, since this post we had got it to work, I’m assuming it was something to with our company firewall. We just created a new EC2 instance allowing for unrestricted network access to, and from which seemed to do the trick. It’s been working well so far but I wonder if you encountered this problem. After I run a compute ‘post’ and I try to run something again sometimes it doesn’t work or takes an extremely long time, have you had this issue?

Thanks