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
How to Access Command Line Arguments
How to Check for Valid Email Address
How to Use a Python Script in the Command Line Without Cd-Ing to Its Directory? Is It the Pythonpath
Get HTML Source of Webelement in Selenium Webdriver Using Python
What Exactly Does "Import *" Import
Creating a Simple Xml File Using Python
Check for Presence of a Sliced List in Python
Access a Function Variable Outside the Function Without Using "Global"
Generate 'N' Unique Random Numbers Within a Range
How to Get a String After a Specific Substring
How to Check If All Elements of a List Match a Condition
How to Check If a String Contains an Element from a List in Python
How to Get User Ip Address in Django
How to Create a Custom String Representation for a Class Object