‘String’ does not contain a definition for ‘key’ error when decoding JSON in Python for Dynamo

‘String’ does not contain a definition for ‘key’ error when decoding JSON in Python for Dynamo

JSON, short for JavaScript Object Notation, is a data-interchange format. It is popular with developers as it is easy for to read and write, and for machines to parse and generate. JSON can be used for Dynamo as well, but ran into some problem while doing so. If you ran into an error stating, ‘string’ does not contain a definition for ‘key’, like I did, you came to the right place.

I will be using a sample JSON object shown below in this post to demonstrate the solution to issue faced.

[
	{
	  "X-Position": 0,
	  "Y-Position": 5,
	  "Z-Position": 2
	},
	{
	  "X-Position": 0,
	  "Y-Position": 2,
	  "Z-Position": 5
	}
]

If you look up the documentation for JSON decoding, the method json.load( ) should produce a Dictionary object as output. However, if you attempt to directly push the Dictionary object as an output from a Python node in Dynamo (shown in the code snippet below). You may run into an error, ‘string’ does not contain a definition for ‘key’, as shown in the image above.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\DLLs')
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib') 
import json

jsonPath = IN[0]
output = []

#Load Json
with open(jsonPath, "r") as read_file:
    data = json.load(read_file)

OUT = data

Solution

I know that there are other solutions, e.g. installing custom packages such as JsonData, I will be demonstrating my preferred solution through code as I prefer to avoid dependencies in my Dynamo graph. We can work around the error by accessing the dictionary directly in the python script by looping through each dictionary and accessing each value by its keys, i.e. “X-Position”, “Y-Position” & “Z-Position”.

value = dictionary[ key ]

The code snippet below yields the result shown above.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\DLLs')
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib') 
import json

jsonPath = IN[0]
output = []

#Load Json
with open(jsonPath, "r") as read_file:
    data = json.load(read_file)

for item in data:
	x = item["X-Position"]
	y = item["Y-Position"]
	z = item["Z-Position"]
	point = Point.ByCoordinates( x, y ,z )
	output.append(point)
	
OUT = output

P.S. This problem have been resolved in Revit 2020 (Output shown below), but not for Revit 2017, 2018 and 2019 when I tested it.

Problem resolved for Revit 2020

I hope this guide has been helpful to you! And feel free to leave your comments below. Happy coding!

This Post Has 5 Comments

  1. JunKang

    Maybe can show a use case whereby you use JSON file?? Which is better, JSON or CSV/xlsx

  2. Arno

    # Load the Python Standard and DesignScript Libraries
    import clr
    clr.AddReference(‘ProtoGeometry’)
    from Autodesk.DesignScript.Geometry import *
    import sys
    sys.path.append(r’C:\Program Files (x86)\IronPython 2.7\DLLs’)
    sys.path.append(r’C:\Program Files (x86)\IronPython 2.7\Lib’)
    import json

    jsonPath = IN[0]

    #Load Json
    with open(jsonPath, “r”) as read_file:
    data = json.load(read_file)

    for item in data:
    Naam = item[“Naam”]
    Locatie = item[“Locatie-NextCloud”]

    OUT = Naam, Locatie

    Why does this not work

    1. Han

      Hello Arno,

      Could I trouble you to send me a sample of your JSON file? I’ll see if I can help.

      Regards,
      Han
      Han@aectechy.com

  3. ปั้มไลค์

    Like!! I blog quite often and I genuinely thank you for your information. The article has truly peaked my interest.

Leave a Reply