Creating a Python object from a Json string

10,319

You could create your own class for that. Use __getitem__, and __setitem__ to get and update values from the object's __dict__ using dot notation:

import json

class PyJSON(object):
    def __init__(self, d):
        if type(d) is str:
            d = json.loads(d)
        self.convert_json(d)

    def convert_json(self, d):
        self.__dict__ = {}
        for key, value in d.items():
            if type(value) is dict:
                value = PyJSON(value)
            self.__dict__[key] = value

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __getitem__(self, key):
        return self.__dict__[key]

rawData = """... raw data ..."""

quake = PyJSON(rawData)

Works as expected:

>>> quake.data.properties.flynn_region
'OAXACA, MEXICO'

EDIT: Added to_dict and overridden __repr__ so it's easier to peek at values in console. Renamed convert_json to from_dict.

import json

class PyJSON(object):
    def __init__(self, d):
        if type(d) is str:
            d = json.loads(d)

        self.from_dict(d)

    def from_dict(self, d):
        self.__dict__ = {}
        for key, value in d.items():
            if type(value) is dict:
                value = PyJSON(value)
            self.__dict__[key] = value

    def to_dict(self):
        d = {}
        for key, value in self.__dict__.items():
            if type(value) is PyJSON:
                value = value.to_dict()
            d[key] = value
        return d

    def __repr__(self):
        return str(self.to_dict())

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __getitem__(self, key):
        return self.__dict__[key]

rawData = """... raw data ..."""

quake = PyJSON(rawData)

Before:

>>> quake.data.geometry
<__main__.PyJSON object at 0xADDRESS>

After:

>>> quake.data.geometry
{'coordinates': [-95.12, 16.52, -52.0], 'type': 'Point'}
Share:
10,319
Zababa
Author by

Zababa

Updated on June 27, 2022

Comments

  • Zababa
    Zababa almost 2 years

    A websocket connection to SeismicPortal is sending me data about earthquakes packed in a JSON object which I get as a multi-line string, e.g.:

    {                                                                                                                                                                                               
        "action": "create",                                                                                                                                                                         
        "data": {                                                                                                                                                                                   
            "geometry": {                                                                                                                                                                           
                "coordinates": [                                                                                                                                                                    
                    -95.12,                                                                                                                                                                         
                    16.52,                                                                                                                                                                          
                    -52.0                                                                                                                                                                           
                ],                                                                                                                                                                                  
                "type": "Point"                                                                                                                                                                     
            },                                                                                                                                                                                      
            "id": "20180303_0000046",                                                                                                                                                               
            "properties": {                                                                                                                                                                         
                "auth": "UNM",                                                                                                                                                                      
                "depth": 52.0,                                                                                                                                                                      
                "evtype": "ke",                                                                                                                                                                     
                "flynn_region": "OAXACA, MEXICO",                                                                                                                                                   
                "lastupdate": "2018-03-03T10:26:00.0Z",                                                                                                                                             
                "lat": 16.52,                                                                                                                                                                       
                "lon": -95.12,                                                                                                                                                                      
                "mag": 4.0,                                                                                                                                                                         
                "magtype": "m",                                                                                                                                                                     
                "source_catalog": "EMSC-RTS",                                                                                                                                                       
                "source_id": "652127",                                                                                                                                                              
                "time": "2018-03-03T07:09:05.0Z",                                                                                                                                                   
                "unid": "20180303_0000046"                                                                                                                                                          
            },                                                                                                                                                                                      
            "type": "Feature"                                                                                                                                                                       
        }                                                                                                                                                                                           
    }
    

    I want to have the data from the string converted to a python object.

    As you see in the JSON data, there is a lot of nesting. As I was defining the classes and their embeddedness to build a on object of a structure which would hold all the data from the JSON I was thinking maybe there is some magic Python function jsonStringToObject which would tailor a class and all subclasses needed to hold all the data in the JSON and make an instance of it.

    Let's have the raw JSON string in the variable rawData:

    rawData = """{"action":"create","data":{"geometry": {"type": "Point","coordinates": [... """
    

    Right now I have to do this:

    >>> import json
    >>> quake = json.loads(rawData)
    >>> quake['data']['properties']['flynn_region']
    "OXACA_MEXICO"
    

    but the syntax is crammed with brackets and apostrophes.

    I wish I could just access the data like this:

    >>> import json    
    >>> quake = jsonStringToObject(rawData)
    >>> quake.data.properties.flynn_region
    "OXACA_MEXICO"
    
  • Philector
    Philector over 5 years
    Where'd k/v come from in convert_json?
  • Božo Stojković
    Božo Stojković over 5 years
    I don't remember how that happened, but from the edits, it seems I wanted to make it more readable, but forgot to update all variable names. Fixed now. Thanks!