0

I'm getting a JSON data from server and I need to parse it separately, when I do this with SimpleNamespace I get the problem. How can I parse this data?

Example Data:

{
  "version":"1.0",
  "packageName":"com.some.thing",
  "eventTimeMillis":"1503349566168",
  "subscriptionNotification":
  {
    "version":"1.0",
    "notificationType":4,
    "purchaseToken":"PURCHASE_TOKEN",
    "subscriptionId":"my.sku"
  }
}

My Code:

import json
from types import SimpleNamespace

def callback(message):
    x = json.loads(message.data, object_hook=lambda d: SimpleNamespace(**d))
    
    print("Version: " + x.version)
    print("Package Name: " + x.packageName)
    print("Time Milis: " + x.eventTimeMillis)
    print("Token: " + x.subscriptionNotification.purchaseToken)
    print("Product: " + x.subscriptionNotification.subscriptionId)
    print("Type: " + str(x.subscriptionNotification.notificationType))

Error:

AttributeError: 'types.SimpleNamespace' object has no attribute 'subscriptionNotification'
6
  • 1
    I tried your code based on your sample data and had no issues. I suspect the message passed to callback() is not quite what you thought it would be. Try print(message) in callback() Commented Oct 5, 2021 at 15:51
  • @BrutusForcus Yes sometimes some mixed data is coming from the server so it crashes. This code generally works fine but sometimes I get errors so I want to do it in a different way. How can I do this outside of SimpleNamespace? Commented Oct 5, 2021 at 15:58
  • Don't use SimpleNamespace - i.e., leave out object_hook. Then, to access the keys, use a traditional get() ideally with a default value - e.g., 'n/a' or None Commented Oct 5, 2021 at 16:05
  • @BrutusForcus I get an error when I try this. x = json.loads(message.data) print("Version: " + x.version) print("Package Name: " + x.packageName) print("Time Milis: " + x.eventTimeMillis) print("Token: " + x.subscriptionNotification.purchaseToken) print("Product: " + x.subscriptionNotification.subscriptionId) print("Type: " + str(x.subscriptionNotification.notificationType)) AttributeError: 'dict' object has no attribute 'version' Commented Oct 5, 2021 at 16:13
  • That's not surprising. I suggested you use get() but you decided against that advice Commented Oct 5, 2021 at 16:20

1 Answer 1

1

In this example, we start with a dictionary. From then on there's very little code and the whole thing becomes "table driven". For example, if your dictionary structure changes such that you add a new key to the top level then you just need to make a corresponding change to the L1 table. Hopefully this will give you some ideas on how to proceed:

D = {
    "version": "1.0",
    "packageName": "com.some.thing",
    "eventTimeMillis": "1503349566168",
    "subscriptionNotification":
    {
        "version": "1.0",
        "notificationType": 4,
        "purchaseToken": "PURCHASE_TOKEN",
        "subscriptionId": "my.sku"
    }
}


def doPrint(d, L):
    if d:
        for _l in L:
            print(f'{_l[0]}: {d.get(_l[1], "n/a")}')


L1 = [['Version', 'version'],
    ['Package Name', 'packageName'],
    ['Time Millis', 'eventTimeMillis']
]
L2 = [['Token', 'purchaseToken'],
    ['Product', 'subscriptionId'],
    ['Type', 'notificationType']
]

doPrint(D, L1)
doPrint(D.get('subscriptionNotification', None), L2)
Sign up to request clarification or add additional context in comments.

2 Comments

Your code works, thanks but I couldn't get it to work for my system. Can you help with this? I am getting the data in def callback(message)
def callback(message): D = json.loads(message.data) print(D) def doPrint(d, L): if d: for _l in L: print(f'{_l[0]}: {d.get(_l[1], "n/a")}') L1 = [['Version', 'version'], ['Package Name', 'packageName'], ['Time Millis', 'eventTimeMillis'] ] L2 = [['Token', 'purchaseToken'], ['Product', 'subscriptionId'], ['Type', 'notificationType'] ] doPrint(D, L1) doPrint(D.get('subscriptionNotification', None), L2)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.