Search code examples
pythonjson-ref

Is there something wrong with this json reference?


I'm trying to take some JSON containing references and resolve them. I'm using the jsonref library to do it. I have reduced my problem to these two cases:

import jsonref

print(jsonref.JsonRef.replace_refs(jsonref.loads('''
{
  "foo": {
    "$ref": "#/def/bar"
  },
  "def": {
      "bar": "baz"
  }
}
''')))
# works: {'foo': 'baz', 'def': {'bar': 'baz'}}

print(jsonref.JsonRef.replace_refs(jsonref.loads('''
{
  "foo": {
    "$ref": "#/def/obj"
  },
  "def": {
    "obj": {
      "bar": "baz"
    }
  }
}
''')))
# expected: {'foo': { 'bar': 'baz'}, 'def': {'bar': 'baz'}}
# actual: AttributeError: 'generator' object has no attribute 'get'

The first one works, but the second one throws an error. Why?


Solution

  • You mean something like this ?

    >>> import jsonref
    >>> s = '''
    ... {
    ...   "foo": {
    ...     "$ref": "#/def/obj"
    ...   },
    ...   "def": {
    ...     "obj": {
    ...       "bar": "baz"
    ...     }
    ...   }
    ... }
    ... '''
    >>> j = jsonref.loads(s)
    >>> j
    {u'foo': {u'bar': u'baz'}, u'def': {u'obj': {u'bar': u'baz'}}}
    >>> 
    

    NB : never used jsonref, didn't even read the doc (!!!) so I can't tell why you get this error, but there's certainly something about the correct way to use it in the doc. But obviously (from a 30s test), jsonref.loads() already applies references replacements and jsonref.JsonRef.replace_refs() is only meant to be used on already unserialized objects, ie:

    >>> s = '''
    ... {
    ...   "foo": {
    ...     "$ref": "#/def/obj"
    ...   },
    ...   "def": {
    ...     "obj": {
    ...       "bar": "baz"
    ...     }
    ...   }
    ... }
    ... '''
    >>> import json
    >>> decoded = json.loads(s) # so we get a plain python dict
    >>> print(decoded)
    {u'foo': {u'$ref': u'#/def/obj'}, u'def': {u'obj': {u'bar': u'baz'}}}
    >>> final = jsonref.JsonRef.replace_refs(decoded)
    >>> print(final)
    {u'foo': {u'bar': u'baz'}, u'def': {u'obj': {u'bar': u'baz'}}}