Search code examples
pythonjsonserializationcamelcasing

JSON serialize a class and change property casing with Python


I'd like to create a JSON representation of a class and change the property names automatically from snake_case to lowerCamelCase, as I'd like to comply with PEP8 in Python and also the JavaScript naming conventions (and maybe even more importantly, the backend I'm communicating to uses lowerCamelCase).

I prefer to use the standard json module, but I have nothing against using another, open source library (e.g. jsonpickle might solve my issue?).

>>> class HardwareProfile:
...     def __init__(self, vm_size):
...             self.vm_size = vm_size
>>> hp = HardwareProfile('Large')
>>> hp.vm_size
'Large'
### ### What I want ### ###
>>> magicjson.dumps(hp)
'{"vmSize": "Large"}'
### ### What I have so far... ### ###
>>> json.dumps(hp, default=lambda o: o.__dict__)
'{"vm_size": "Large"}'

Solution

  • You just need to create a function to transform the snake_case keys to camelCase. You can easily do that using .split, .lower, and .title.

    import json
    
    class HardwareProfile:
        def __init__(self, vm_size):
            self.vm_size = vm_size
            self.some_other_thing = 42
            self.a = 'a'
    
    def snake_to_camel(s):
        a = s.split('_')
        a[0] = a[0].lower()
        if len(a) > 1:
            a[1:] = [u.title() for u in a[1:]]
        return ''.join(a)
    
    def serialise(obj):
        return {snake_to_camel(k): v for k, v in obj.__dict__.items()}
    
    hp = HardwareProfile('Large')
    print(json.dumps(serialise(hp), indent=4, default=serialise))
    

    output

    {
        "vmSize": "Large",
        "someOtherThing": 42,
        "a": "a"
    }
    

    You could put serialise in a lambda, but I think it's more readable to write it as a proper def function.