Search code examples
pythonmarshmallow

how to deserialize JSON with keys that are not valid Python names in marshmallow


I'm getting a JSON object with a key "sera:blah"

How would I deserialize that object into a python data type using the marshmallow library as that colon is an invalid property name?

Edit:

So classes in python cannot accept a colon in the porperty name. It's invalid syntax.

Edit2:

Ideally I would like to have a workaround within marshmallow.


Solution

  • I see 2 routes you can take with this

    • Try to deserialize it with JSON.loads first, and iterate through each property and replace all the malformed keys before feeding it to marshmallow, or
    • Use the JSON.JSONDecoder class and roll your own object_hook function. Then call the .decode() function before feeding it to marshmallow.

    I've expanded on the latter (which I think is more appropriate)

    from json import loads, JSONDecoder
    s = """{
      "obj1": 123,
      "list": [
        {"example2": 42},
        {"sera:blah": false},
        {"object:3": {"nest:ed": "obj"}}
      ]
    }"""
    
    data = loads(s)
    print(data)
    
    def obj_transform(obj):
      for key in obj.keys():  # Iterate through obj
        if ':' in key:
          obj[key.replace(':', '_')] = obj.pop(key)
      return obj
    
    decoder = JSONDecoder(object_hook=obj_transform)
    print(decoder.decode(s))
    

    The result of this prints:

    {'obj1': 123, 'list': [{'example2': 42}, {'sera:blah': False}, {'object:3': {'nest:ed': 'obj'}}]}
    {'obj1': 123, 'list': [{'example2': 42}, {'sera_blah': False}, {'object_3': {'nest_ed': 'obj'}}]}

    Which seems like what you are looking for, to sanitize your input to marshmallow.