How to Convert JSON Data into a Python Object

How to convert JSON data into a Python object?

You could try this:

class User(object):
def __init__(self, name, username):
self.name = name
self.username = username

import json
j = json.loads(your_json)
u = User(**j)

Just create a new object, and pass the parameters as a map.


You can have a JSON with objects too:

import json
class Address(object):
def __init__(self, street, number):
self.street = street
self.number = number

def __str__(self):
return "{0} {1}".format(self.street, self.number)

class User(object):
def __init__(self, name, address):
self.name = name
self.address = Address(**address)

def __str__(self):
return "{0} ,{1}".format(self.name, self.address)

if __name__ == '__main__':
js = '''{"name":"Cristian", "address":{"street":"Sesame","number":122}}'''
j = json.loads(js)
print(j)
u = User(**j)
print(u)

Python Convert JSON Array to Corresponding List of Python Objects

If you're ok with using external libraries, the simplest solution would be to use the builtin dataclasses module in Python 3.7+ along with the dataclass-wizard library for (de)serialization purposes.

Here's a simple enough example using data classes to model your data in this case. Note that I'm using a new feature, patterned date and time, to de-serialize a custom pattern string to a datetime object. If you want to keep the data as a string, you can annotate it just like deadline: str instead. I was able to use the format codes from the docs on datetime.

import json
from dataclasses import dataclass

from dataclass_wizard import fromlist, asdict, DateTimePattern

@dataclass
class Task:
completed: int
content: str
deadline: DateTimePattern['%a, %d %b %Y %H:%M:%S %Z']
id: int
user_id: int

list_of_dict = [
{'completed': 0, 'content': 'do smtng', 'deadline': 'Mon, 22 Nov 2021 00:00:00 GMT', 'id': 4, 'user_id': 7},
]

# De-serialize JSON data into a list of Task instances
list_of_tasks = fromlist(Task, list_of_dict)
print(list_of_tasks)

# Serialize list of Task instances
json_string = json.dumps([asdict(task) for task in list_of_tasks])
print(json_string)

Output:

[Task(completed=0, content='do smtng', deadline=datetime.datetime(2021, 11, 22, 0, 0), id=4, user_id=7)]
[{"completed": 0, "content": "do smtng", "deadline": "2021-11-22T00:00:00", "id": 4, "userId": 7}]

To make things a bit simpler, you can opt to subclass from the JSONWizard Mixin class. The main benefit here is a bunch of added helper class methods, like list_to_json which will serialize a list of dataclass instances to JSON, which seems like it could be useful in this case. This example is similar to the one above; note the output is the same in any case.

from dataclasses import dataclass

from dataclass_wizard import JSONWizard, DateTimePattern

@dataclass
class Task(JSONWizard):
completed: int
content: str
deadline: DateTimePattern['%a, %d %b %Y %H:%M:%S %Z']
id: int
user_id: int

list_of_dict = [
{'completed': 0, 'content': 'do smtng', 'deadline': 'Mon, 22 Nov 2021 00:00:00 GMT', 'id': 4, 'user_id': 7},
]

# De-serialize JSON data into a list of Task instances
list_of_tasks = Task.from_list(list_of_dict)
print(list_of_tasks)

# Serialize list of Task instances
json_string = Task.list_to_json(list_of_tasks)
print(json_string)

Creating a Python object from a Json string

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'}

how to convert json to python class?

Use object_hook special parameter in load functions of json module:

import json

class JSONObject:
def __init__( self, dict ):
vars(self).update( dict )

#this is valid json string
data='{"channel":{"lastBuild":"2013-11-12", "component":["test1", "test2"]}}'

jsonobject = json.loads( data, object_hook= JSONObject)

print( jsonobject.channel.component[0] )
print( jsonobject.channel.lastBuild )

This method have some issue, like some names in python are reserved. You can filter them out inside __init__ method.

How to convert json to object?

The following lines will give you a dictionary:

obj = jsonpickle.decode(result.content)  # NOTE: `.content`, not `.json`

obj = result.json()

But none of above will give you what you want (python object (not dicitonary)). because the json from the url is not encoded with jsonpickle.encode - whcih add additional information to a generated json (something like {"py/object": "__main__.Goal", ....})


>>> import jsonpickle
>>> class Goal(object):
... def __init__(self):
... self.GoaldID = -1
... self.IsPenalty = False
...
>>> jsonpickle.encode(Goal())
'{"py/object": "__main__.Goal", "IsPenalty": false, "GoaldID": -1}'
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# JSON encoded with jsonpickle.encode (default unpicklable=True)
# => additional python class information attached
# => can be decoded back to Python object
>>> jsonpickle.decode(jsonpickle.encode(Goal()))
<__main__.Goal object at 0x10af0e510>

>>> jsonpickle.encode(Goal(), unpicklable=False)
'{"IsPenalty": false, "GoaldID": -1}'
# with unpicklable=False (similar output with json.dumps(..))
# => no python class information attached
# => cannot be decoded back to Python object, but a dict
>>> jsonpickle.decode(jsonpickle.encode(Goal(), unpicklable=False))
{'IsPenalty': False, 'GoaldID': -1}

If you want an actual Python object which is not a dictionary, i.e. you prefer dic.Goals.[0].GoalGetterName to dic["Goals"][0]["GoalGetterName"], use json.loads with object_hook:

import json
import types
import requests

url = "https://www.openligadb.de/api/getmatchdata/39738"

result = requests.get(url)
data = json.loads(result.content, object_hook=lambda d: types.SimpleNamespace(**d))
# OR data = result.json(object_hook=lambda d: types.SimpleNamespace(**d))
goal_getter = data.Goals[0].GoalGetterName
# You get `types.SimpleNamespace` objects in place of dictionaries

How can I convert Json data that coming from Postman convert into Integers in python?

You care less about the integers, you want datetime objects. You have decided that you want <year>, <month>, <day> as your incoming serialised JSON format for dates.

So you might do:

from datetime import datetime

pattern = "%Y, %m, %d"
from_date = datetime.strptime(fromDate, pattern)
to_date = datetime.strptime(toDate, pattern)

You might want to add validations, e.g. assert from_date <= to_date etc. depending on your use case.

I also recommend you look into ISO 8601 date formats, as a more standardised way of serialising dates.

Debug Notes, try this based on your comments:

@app.route("/", methods=['POST', 'GET'])
def historyOrderTotal():
fromDate = None
toDate = None
if request.method == 'POST':
fromDate = request.json['fromDate']
toDate = request.json['toDate']
print("json-from:", fromDate)
print("json-to:", toDate)
pattern = "%Y, %m, %d"
from_date = datetime.strptime(fromDate, pattern)
to_date = datetime.strptime(toDate, pattern)
print("parsed-from:", from_date)
print("parsed-to:", to_date)
if mt.initialize():
history_orders = mt.history_orders_total(from_date, to_date)
print("history-orders", history_orders)
else:
print("initialize() failed, error code =", mt.last_error())
else:
print(">> Not a POST request")

Deserialize a json string to an object in python

>>> j = '{"action": "print", "method": "onData", "data": "Madan Mohan"}'
>>> import json
>>>
>>> class Payload(object):
... def __init__(self, j):
... self.__dict__ = json.loads(j)
...
>>> p = Payload(j)
>>>
>>> p.action
'print'
>>> p.method
'onData'
>>> p.data
'Madan Mohan'


Related Topics



Leave a reply



Submit