Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

JSON Python parsing error KeyError: 'vrm'

I have stitched together the below python code and I’m struggling with a KeyError: 'vrm'.

My aim is to parse the JSON string and only print the specific JSON objects.

#!/usr/bin/python3
import json

class Vehicle:
    def __init__(self,responseInfo, code, desc, data, vrm, vin, engineNumber, capId, capCode, manufacturer, model, vehicleType, registrationDate, firstRegistrationDate, body, doors, engineSize, fuel, fuelDelivery, transmission, isScraped, isExported, isImported, images, exactMatch, url, mainImage):
        self.responseInfo = responseInfo
        self.code = code
        self.desc = desc
        self.data = data
        self.vrm = vrm
        self.vin = vin
        self.engineNumber = engineNumber
        self.capId = capId
        self.capCode = capCode
        self.manufacturer = manufacturer
        self.model = model
        self.vehicleType = vehicleType
        self.registrationDate = registrationDate
        self.firstRegistrationDate = firstRegistrationDate
        self.body = body
        self.doors = doors
        self.engineSize = engineSize
        self.fuel = fuel
        self.fuelDelivery = fuelDelivery
        self.transmission = transmission
        self.isScraped = isScraped
        self.isExported = isExported
        self.isImported = isImported
        self.images = images
        self.exactMatch = exactMatch
        self.url = url
        self.mainImage = mainImage

def vehicleDecoder(obj):
        return Vehicle(obj['vrm'], obj['vin'], obj['engineNumber'], obj['capId'], obj['capCode'], obj['manufacturer'], obj['model'], obj['vehicleType'], obj['registrationDate'], obj['firstRegistrationDate'], obj['body'], obj['doors'], obj['engineSize'], obj['fuel'], obj['fuelDelivery'], obj['transmission'], obj['isScraped'], obj['isExported'], obj['isImported'], obj['images'], obj['exactMatch'], obj['url'], obj['mainImage'])

vehicleObj = json.loads('{"responseInfo":{"code":0,"desc":"Success"},"data":{"vrm":"MA71VWG","vin":"WBATS120009H40802","engineNumber":"A1566412","capId":91400,"capCode":"BMX320MS 5EXTA4 4","manufacturer":"BMW","model":"X3","vehicleType":"Car","registrationDate":"27/09/21","firstRegistrationDate":"27/09/21","body":"Estate","doors":"5","engineSize":"1998","fuel":"Petrol/PlugIn Elec Hybrid","fuelDelivery":"Turbo","transmission":"Automatic","isScraped":"No","isExported":"No","isImported":"No","images":[{"viewpoint":"Front Three Quarter","exactMatch":true,"url":"https://soap.cap.co.uk/images/VehicleImage.aspx?SUBID=171774&HASHCODE=92A987528AB2F2215A7372DADD8CE57C&DB=CAR&CAPID=91400&WIDTH=&HEIGHT=&IMAGETEXT=&VIEWPOINT=3","mainImage":true}]}}')
print(vehicleObj) #works
#vehicleObj = (vehicleObj['data'])
print(vehicleObj) #works
vehicleObj = json.dumps(vehicleObj)
print(vehicleObj)
vehicleObj = json.loads(str(vehicleObj), object_hook=vehicleDecoder)
#print(vehicleObj)
print(vehicleObj.vrm, vehicleObj.vin, vehicleObj.engineNumber, vehicleObj.capId, vehicleObj.capCode, vehicleObj.manufacturer, vehicleObj.model, vehicleObj.vehicleType, vehicleObj.registrationDate, vehicleObj.firstRegistrationDate, vehicleObj.body, vehicleObj.doors, vehicleObj.engineSize, vehicleObj.fuel, vehicleObj.fuelDelivery, vehicleObj.transmission, vehicleObj.isScraped, vehicleObj.isExported, vehicleObj.isImported)

Error output below

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Traceback (most recent call last):
  File "C:\Users\jack\Desktop\Python-Project\test.py", line 42, in <module>
    vehicleObj = json.loads(str(vehicleObj), object_hook=vehicleDecoder)
  File "C:\Python\Python39\lib\json\__init__.py", line 359, in loads
    return cls(**kw).decode(s)
  File "C:\Python\Python39\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Python\Python39\lib\json\decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
  File "C:\Users\jack\Desktop\Python-Project\test.py", line 34, in vehicleDecoder
    return Vehicle(obj['vrm'], obj['vin'], obj['engineNumber'], obj['capId'], obj['capCode'], obj['manufacturer'], obj['model'], obj['vehicleType'], obj['registrationDate'], obj['firstRegistrationDate'], obj['body'], obj['doors'], obj['engineSize'], obj['fuel'], obj['fuelDelivery'], obj['transmission'], obj['isScraped'], obj['isExported'], obj['isImported'], obj['images'], obj['exactMatch'], obj['url'], obj['mainImage'])
KeyError: 'vrm'

Can anyone spot where I’ve gone wrong or have a better solution to parse JSON output?

>Solution :

If you reduce this example down to the minimum required to trigger the problem, the issue is much more clear:

import json


class Vehicle:
    def __init__(self, vrm):
        self.vrm = vrm


def vehicleDecoder(obj):
        return Vehicle(obj['vrm'])

vehicle_str = '{"data":{"vrm":"MA71VWG"}}'

vehicleObj = json.loads(vehicle_str, object_hook=vehicleDecoder)

This still creates a KeyError. Why? When loading a json, the object hook is called on every object. You probably intended for it to be called on the object containing the "vrm" key, but technically the {"data": ... part is an object too.

How can you fix this? Don’t use object_hook. Parse the json like this:

vehicleJson = json.loads(...)
vehicleObj = vehicleDecoder(vehicleJson['data'])
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading