Cove.Tool Rest API via Python in Dynamo

Hello.

The below code is python which is put into a Python node in Grasshopper to send data to Cove.Tool’s REST API endpoint.

import rhinoscriptsyntax as rs
import json, ssl, urllib2

from System.Net import WebRequest
from System.IO import StreamReader
from System.Text import Encoding

class ApiHelpers:
def init(self, token):
self.token = token

def post_request(self, path, data, use_token=True):
    url = self._api_url(path)
    data = json.dumps(data)
    headers = self._headers(use_token)
    request = urllib2.Request(url, data=data, headers=headers)
    try:
        response = urllib2.urlopen(request)
    except Exception as e:
        try:
            result = self.legacy_url_open(url, use_token, data)
            return result
        except Exception as e:
            print(e)
            return {'result': 'error'}
    return json.load(response)

def get_request(self, path, use_token=True):
    url = self._api_url(path)
    headers = self._headers(use_token)
    request = urllib2.Request(url, headers=headers)
    try:
        response = urllib2.urlopen(request)
    except Exception as e:
        try:
            result = self.legacy_url_open(url, use_token)
            return result
        except Exception as e:
            print(e)
            return {'result': 'error'}
    return json.load(response)
    
def legacy_url_open(self, url, use_token, data=None):
    request = WebRequest.Create(url)
    request.ContentType = "application/json"
    if use_token:
        request.Headers.Add('Authorization', 'Token ' + self.token)
    if data:
        request.Method = "POST"
        bytes = Encoding.ASCII.GetBytes(data)
        request.ContentLength = bytes.Length
        request_stream = request.GetRequestStream()
        request_stream.Write(bytes, 0, bytes.Length)
        request_stream.Close()

    response = request.GetResponse()
    result = StreamReader(response.GetResponseStream()).ReadToEnd()
    return json.loads(result)

def _api_url(self, path):
    return 'https://app.covetool.com/api/' + path + '/'

def _headers(self, use_token):
    headers = {
        "Content-Type": "application/json",
    }
    if use_token:
        headers['Authorization'] = 'Token ' + self.token
    return headers

Execution

helpers = ApiHelpers(token)

unit_system = rs.UnitSystem()
if unit_system == 4:
unit_system = “Unit System: Meters”
si_units = “true”
elif unit_system == 9:
unit_system = “Unit System: Feet”
si_units = “false”
else:
unit_system = “Unit System: Not Meters or Feet”
raise RuntimeError(“Units should be Meters or Feet”)

data = {
‘run’: run,
‘si_units’: si_units,
‘building_height’: building_height,
‘roof_area’: roof_area,
‘floor_area’: floor_area,
‘skylight_area’: skylight_area,
‘wall_area_e’: wall_area_e,
‘wall_area_ne’: wall_area_ne,
‘wall_area_n’: wall_area_n,
‘wall_area_nw’: wall_area_nw,
‘wall_area_w’: wall_area_w,
‘wall_area_sw’: wall_area_sw,
‘wall_area_s’: wall_area_s,
‘wall_area_se’: wall_area_se,
‘window_area_e’: window_area_e,
‘window_area_ne’: window_area_ne,
‘window_area_n’: window_area_n,
‘window_area_nw’: window_area_nw,
‘window_area_w’: window_area_w,
‘window_area_sw’: window_area_sw,
‘window_area_s’: window_area_s,
‘window_area_se’: window_area_se,
}

result = helpers.post_request(‘run-values’, data)
eui_total = result[‘data’][‘eui_total’]
print(‘EUI Total:’, eui_total)
cooling = 0
heating = 0
lighting = 0
equipment = 0
fans = 0
pumps = 0
hot_water = 0
pv_energy = 0
eui_breakdown = result[‘data’][‘eui_breakdown’]
headers = eui_breakdown[‘headers’]
values = eui_breakdown[‘values’]
for i, header in enumerate(headers):
value = float(values[i])
if header == ‘Cooling’:
cooling = value
print(‘Cooling:’, cooling)
elif header == ‘Heating’:
heating = value
print(‘Heating:’, heating)
elif header == ‘Lighting’:
lighting = value
print(‘Lighting:’, lighting)
elif header == ‘Equipment’:
equipment = value
print(‘Equipment:’, equipment)
elif header == ‘Fans’:
fans = value
print(‘Fans:’, fans)
elif header == ‘Pumps’:
pumps = value
print(‘Pumps:’, pumps)
elif header == ‘Hot Water’:
hot_water = value
print(‘Hot Water:’, hot_water)
elif header == ‘PV Energy’:
pv_energy = value
print(‘PV Energy:’, pv_energy)

WHen, I try to implement in Dynamo I get a warning that JSON cannot be incorporated into the Dynamo python node.

Any suggestions on how to re-write this so that it works in Dynamo?

For certain modules, you have to first append the IronPython lib folder to your path before being able to import them. Write this before your import json statement:

import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')

I believe this has been resolved in Revit 2020 and later, but for the sake of compatibility you may want to include it anyway.

2 Likes