# Function to convert json string or python dict into ObjectWrapper

**URL:** <https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861>\
**Category:** Ignition\
**Created:** [March 5, 2020, 10:45pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861 "2020-03-05T22:45:39Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jonathan](https://avatars.discourse-cdn.com/v4/letter/j/aeb1de/32.png) [@Jonathan](https://forum.inductiveautomation.com/u/Jonathan)\
**Post date:** [March 5, 2020, 10:45pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/1 "2020-03-05T22:45:39Z")

</div>

Is there a function out there that will turn a json string or python dict into ObjectWrapper?

If I take a python dict and assign it to a property on a perspective view it turn the property into a object. It I then go and get the property in script the property does not come back as a dictionary it comes back as an ObjectWrapper. What I want to do in script is go from a dictionary to an object wrapper without having to assing it to a view property.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 5, 2020, 10:52pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/2 "2020-03-05T22:52:47Z")

</div>

Why?  
What’s your end goal, if you create an ObjectWrapper?

---

<div class="post-metadata">

**Author:** ![Jonathan](https://avatars.discourse-cdn.com/v4/letter/j/aeb1de/32.png) [@Jonathan](https://forum.inductiveautomation.com/u/Jonathan)\
**Post date:** [March 5, 2020, 11:10pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/3 "2020-03-05T23:10:23Z")

</div>

We have objects that we serialized and stored on the views. Then later when we need that object we can deserialize the ObjectWrapper.

The problem now is I want to store the serialized object in a string tag, but when I pull it back out and try the existing deserializing it does not work because I cannot reference the string like the ObjectWrapper. I also tried using system.util.jsonDecode(), but that turns it into a dictionary and I cannot reference the properties the same way

e.g.

object.property1  
object.property2

If you had a function to turn an ObjectWrapper into a python dictionary I could probably make that work with out to much refactoring on our side.

I would then have to change all our deserialize functions to reference properties like this

object[“property1”]  
object[“property2”]

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 5, 2020, 11:28pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/4 "2020-03-05T23:28:33Z")

</div>

You should be able to `dict(<objectWrapper>)` within a release or two; I opened a PR for that last week, just needs QA sign off. That’s probably going to be the sanest way forward; you most likely won’t have any success trying to manually convert an object into one of the wrapper types.

I’d also highly recommend migrating towards the ` __getitem__ `/braces syntax, over attribute retrieval. We make that work to make things nicer for anyone more used to working with JS objects, but it’s got limitations from a Pythonic perspective.

---

<div class="post-metadata">

**Author:** ![Jonathan](https://avatars.discourse-cdn.com/v4/letter/j/aeb1de/32.png) [@Jonathan](https://forum.inductiveautomation.com/u/Jonathan)\
**Post date:** [March 5, 2020, 11:33pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/5 "2020-03-05T23:33:38Z")

</div>

Great thanks. I did not know you could use the brace syntax on the view propriety objects. That may just fix my issue.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 6, 2020, 12:08am UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/6 "2020-03-06T00:08:43Z")

</div>

Actually, what’s the full `str(type(<wrapper>))`? If it’s a `PropertyTreeScriptWrapper$ObjectWrapper` I would expect dict() to work right now, assuming you’re on 8.0.5+.

---

<div class="post-metadata">

**Author:** ![Jonathan](https://avatars.discourse-cdn.com/v4/letter/j/aeb1de/32.png) [@Jonathan](https://forum.inductiveautomation.com/u/Jonathan)\
**Post date:** [March 6, 2020, 12:35am UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/7 "2020-03-06T00:35:03Z")

</div>

yes I am on 8.0.7

> com.inductiveautomation.perspective.gateway.script.PropertyTreeScriptWrapper$ObjectWrapper

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [May 5, 2021, 4:15pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/8 "2021-05-05T16:15:04Z")

</div>

@paul-griffith  
I’m trying to do this as well. I have a custom param that’s an Object with this format:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/d/0d9434047510d07462d931857ecc8e7a09775127.png)

When I use dict() to convert to a dict, the base controlAccess works fine, but its key values are still ObjectWrappers. I assume i’m going to have to loop through it and convert all ObjectWrappers into dicts?

I’ve just tried this and I can’t import the object:  
`import com.inductiveautomation.perspective.gateway.script.PropertyTreeScriptWrapper`

With the error:  
`ImportError: No module named perspective`

v8.1.5

This works, but yuck!  
`str(type(dict(self.view.custom.controlAccess)['racking'])) == "<type 'com.inductiveautomation.perspective.gateway.script.PropertyTreeScriptWrapper$ObjectWrapper'>"`

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 5, 2021, 4:25pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/9 "2021-05-05T16:25:40Z")

</div>

What’s your exact script? Doing the obvious thing seems to work for me:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/d/0daa3f507f19907ef9b9b3e68cc4c1909086ceb5.png)

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [May 5, 2021, 4:27pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/10 "2021-05-05T16:27:59Z")

</div>

Can you print out:  
`type(dict(self.custom.controlAccess)['racking'])`?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 5, 2021, 4:34pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/11 "2021-05-05T16:34:05Z")

</div>

Ah, so it is an ObjectWrapper...  
Interesting. I'm actually not sure whether we can 'fix' that; it'd be nice if `dict` was automatically recursive, but c'est la vie. We'd have to introduce a new method, which sounds pretty gross...

You could make your deep to-dict function not care about specific types by relying on the presence of Python magic methods, as in this post:

> [@\[IGN-5231\] jsonEncode issue](http://forum.inductiveautomation.com/t/jsonencode-issue/44603/26):
>
> In case others end up fighting this later and are having trouble finding the bad sub-elements of a bigger structure, this is a quick bit of debug code I put together to show the data types of a structure before passing it into jsonEncode: def type\_tree(element, prefix='/'): type\_string = str(type(element)) output\_string = '{}={}\n'.format(prefix, type\_string) if hasattr(element, '\_\_iter\_\_'): if hasattr(element, 'keys'): for key in element.keys(): …

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [May 5, 2021, 4:39pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/12 "2021-05-05T16:39:03Z")

</div>

Cool, that looks useful 🙂  
What I’m trying to do is to make a copy of that controlAccess object, manipulate it, then write it back. What I found was that if I just assigned a variable to it e.g. `controlAccess = self.custom.controlAccess`, the controlAccess python variable became a reference to the View’s custom property, which I thought was a bit strange.  
Is there a better way to do this, rather than converting things all to dicts? can I make a copy like dict’s `copy()` method of an ObjectWrapper object?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 5, 2021, 4:46pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/13 "2021-05-05T16:46:57Z")

</div>

Well, `dict.copy()` is just a shallow copy - it’s basically doing exactly what `dict(<some dict>)` would do. A less performant, but maybe easier solution would be to `json.loads(json.dumps(self.custom.controlAccess))` - that’ll be an easy deep-copy. (The same technique is common in the front-end world).

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [May 5, 2021, 4:49pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/14 "2021-05-05T16:49:36Z")

</div>

No dice ☹

```auto
 File "C:\Program Files\Inductive Automation\Ignition\user-lib\pylib\json\ __init__.py", line 243, in dumps
    return _default_encoder.encode(obj)
  File "C:\Program Files\Inductive Automation\Ignition\user-lib\pylib\json\encoder.py", line 206, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Program Files\Inductive Automation\Ignition\user-lib\pylib\json\encoder.py", line 269, in iterencode
    return _iterencode(o, 0)
  File "C:\Program Files\Inductive Automation\Ignition\user-lib\pylib\json\encoder.py", line 183, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: {u'vent': {u'enabled': False}, u'sump': {u'enabled': False}, u'scanTimeStamp': None, u'gas': {u'enabled': False}, u'racking': {u'enabled': False}} is not JSON serializable

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 5, 2021, 5:07pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/15 "2021-05-05T17:07:47Z")

</div>

Oh, right. The builtin JSON function is a little weird. Either of these seem to work:

```auto
	import json
	from java.util import Date
	
	class IgnitionEncoder(json.JSONEncoder):
		def default(self, obj):
			if isinstance(obj, Date):
				return obj.time
			elif hasattr(obj, "keys"):
				return dict(obj)
			elif hasattr(obj, " __iter__"):
				return list(obj)
			return json.JSONEncoder.default(self, obj)
	
	j = json.dumps(self.custom.controlAccess, cls=IgnitionEncoder, indent=4)
	system.perspective.print(j)

```

```auto
	from com.inductiveautomation.ignition.common import TypeUtilities
	system.perspective.print(TypeUtilities.gsonToPy(TypeUtilities.pyToGson(self.custom.controlAccess)))

```

---

<div class="post-metadata">

**Author:** ![justin.brzozoski](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justin.brzozoski/32/13452_2.png) [@justin.brzozoski](https://forum.inductiveautomation.com/u/justin.brzozoski)\
**Post date:** [May 5, 2021, 8:20pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/16 "2021-05-05T20:20:59Z")

</div>

Forcing each to the expected type while traversing makes a deep copy:

```auto
def sanitize_tree(element):
    if hasattr(element, ' __iter__'):
        if hasattr(element, 'keys'):
            return dict((k, sanitize_tree(element[k])) for k in element.keys())
        else:
            return list(sanitize_tree(x) for x in element)
    return element

```

EDIT: Got rid of the unnecessary zip() and used only one keys() iterator instead of two.

---

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [January 8, 2024, 10:20pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/17 "2024-01-08T22:20:00Z")

</div>

There seems to be a limitation on the number of nested dictionaries with this function, unless I'm using it wrong?  
e.g.

```auto
def sanitize_tree(element):
	'''Take a Perspective ObjectWrapper Tree and convert to python dict or list'''
	if hasattr(element, ' __iter__'):
		if hasattr(element, 'keys'):
			return dict((k, sanitize_tree(element[k])) for k in element.keys())
        else:
            return list(sanitize_tree(x) for x in element)
	return element

top= {'top':{}}
print sanitize_tree(top)

inner1 = {'top': {'inner1': {}}}
print sanitize_tree(inner1)

inner2 = {'top': {'inner1': {'inner2':'test'}}}
print sanitize_tree(inner2)

```

result

```auto
{'top': {}}
{'top': {'inner1': {}}}
Traceback (most recent call last):
  File "<input>", line 37, in <module>
  File "<input>", line 25, in sanitize_tree
...
RuntimeError: maximum recursion depth exceeded (Java StackOverflowError)

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 8, 2024, 10:33pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/18 "2024-01-08T22:33:26Z")

</div>

> [@dkhayes117](#):
>
> `maximum recursion depth exceeded`

That usually happens when an inner element points at one of its parents.

---

<div class="post-metadata">

**Author:** ![justin.brzozoski](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justin.brzozoski/32/13452_2.png) [@justin.brzozoski](https://forum.inductiveautomation.com/u/justin.brzozoski)\
**Post date:** [January 9, 2024, 3:23pm UTC](https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/19 "2024-01-09T15:23:28Z")

</div>

Whitespace errors... Most of my sample is space-indented, but you have a mix of tab-indents. Go double-check...
