I have been tasked with combining data from two different sources into one JSON to be used by a web service. I decided to go with flask which I have found to be so easy to use.
Anyway, I am retrieving JSON that looks like this ( via urlib2 )....
[
[{
"timestamp": 1474088400000,
"errors": 1018831,
"errorTotal": 72400021,
"errorTotal2": 0.013022892930509898,
"business": 4814994,
"breakdown": [{
"type": "type1",
"count": 603437
}, {
"type": "type2",
"count": 256187
}]
}]
]
All I am trying to do is add a new key pair under "breakdown", specifically "type3", so the JSON object looks like this...
[
[{
"timestamp": 1474088400000,
"errors": 1018831,
"errorTotal": 72400021,
"errorTotal2": 0.013022892930509898,
"business": 4814994,
"breakdown": [{
"type": "type1",
"count": 603437
}, {
"type": "type2",
"count": 256187
}, {
"type": "type3",
"count": 4533
}]
}]
]
I thought treating it like key pairs in a list would be the way to go but it doesn't seem to be working. Can anyone point me in the right direction ?
Many thanks in advance!
First, you should read the json into Python objects:
data = json.loads(jsonstring)
Then get to the object to be modified. The data looks like [ [ {... 'breakdown': ...} ] ], so it is a list of lists of dictionaries. I guess you want all of them:
for d in data:
for dd in d:
d['breakdown'].append({"type": "type3", "count": 4533})
Then convert it back to json:
update_json = json.dumps(data)
Load the json string
json_data = json.loads(json_string)
Iterate over the object and append to the "breakdown" key
for item in json_data:
for json_dict in item:
json_dict["breakdown"].append({"type": "type3", "count": 4533})
Convert it back to the JSON string
json_string = json.dumps(json_data)
Related
I have a dict like below with hundreds of "assets". I would like to get the key="href" and print the url but because all "assets" are in a list and the first key of "assets" is changing I havent found a way to get there. Thanks for helping!
d = {"features": [
{
"assets": {
"swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip": {
"checksum:multihash":
"1220A94A04BD19E190139FAD49E6174DE82987221F7330DDEB7F6943AEAC3D7C4C78",
"created": "2021-02-10T17:51:31.618859Z",
"href":
"https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-24/swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip",
"proj:epsg": 2056,
"type": "application/x.dxf+zip",
"updated": "2021-02-10T17:51:31.618877Z"
}
}
},
{
"assets": {
"swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip": {
"checksum:multihash":
"1220EA3AFCCDE8648CB60CDF17AF679458233DE2E6052CBBB91F058CBCA651191F6D",
"created": "2021-02-10T17:51:33.722985Z",
"href":
"https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-42/swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip",
"proj:epsg": 2056,
"type": "application/x.dxf+zip",
"updated": "2021-02-10T17:51:33.723005Z"}
}
}
]}
Try this one.
output_list = []
for data_dict in d['features']:
for key, value_dict in data_dict['assets'].items():
output_list.append(value_dict['href'])
print(output_list)
Output:
['https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-24/swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip', 'https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-42/swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip']
If the dictionary in your example is assigned to a variable called d, this works:
result = [(next(iter(x['assets'])), x['assets'][next(iter(x['assets']))]['href']) for x in d['features']]
print(result)
Output:
[('swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip', 'https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-24/swissbuildings3d_2_2018-07_1064-24_2056_5728.dxf.zip'), ('swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip', 'https://data.geo.admin.ch/ch.swisstopo.swissbuildings3d_2/swissbuildings3d_2_2018-07_1064-42/swissbuildings3d_2_2018-07_1064-42_2056_5728.dxf.zip')]
If what you shared wasn't in fact a dictionary, but a .json file, this is how to get it all the same:
import json
with open('mydata.json') as f:
d = load.loads(f.read())
I am fairly new to using APIs in python and I am trying to create a system that outputs data from previous motorsport races. I have sent requests to an API, but I am struggling to get it to just output one specific piece of data (eg. time, location). I get this when I just print the raw JSON data sent.
{
"MRData": {
"RaceTable": {
"Races": [
{
"Circuit": {
"Location": {
"country": "Spain",
"lat": "41.57",
"locality": "Montmeló",
"long": "2.26111"
},
"circuitId": "catalunya",
"circuitName": "Circuit de Barcelona-Catalunya",
"url": "http://en.wikipedia.org/wiki/Circuit_de_Barcelona-Catalunya"
},
"date": "2020-08-16",
"raceName": "Spanish Grand Prix",
"round": "6",
"season": "2020",
"time": "13:10:00Z",
"url": "https://en.wikipedia.org/wiki/2020_Spanish_Grand_Prix"
}
],
"round": "6",
"season": "2020"
},
"limit": "30",
"offset": "0",
"series": "f1",
"total": "1",
"url": "http://ergast.com/api/f1/2020/6.json",
"xmlns": "http://ergast.com/mrd/1.4"
}
}
Just to get to grips with APIs I am simply trying to output a simple piece of data of a specific race, and once I can do that, I'll be able to scale it up and output all sorts of data. I'd assumed it would just be as simple as typing print(data['time']) (as seen below) but I get an error message saying this:
KeyError: 'time'
My source code:
import requests
response = requests.get("http://ergast.com/api/f1/2020/6.json")
data = response.json()
print (data["time"])
Any help is appreciated!
Like this...
import json
data = """{
"MRData":{
"xmlns":"http://ergast.com/mrd/1.4",
"series":"f1",
"url":"http://ergast.com/api/f1/2020/6.json",
"limit":"30",
"offset":"0",
"total":"1",
"RaceTable":{
"season":"2020",
"round":"6",
"Races":[
{
"season":"2020",
"round":"6",
"url":"https://en.wikipedia.org/wiki/2020_Spanish_Grand_Prix",
"raceName":"Spanish Grand Prix",
"Circuit":{
"circuitId":"catalunya",
"url":"http://en.wikipedia.org/wiki/Circuit_de_Barcelona-Catalunya",
"circuitName":"Circuit de Barcelona-Catalunya",
"Location":{
"lat":"41.57",
"long":"2.26111",
"locality":"Montmeló",
"country":"Spain"
}
},
"date":"2020-08-16",
"time":"13:10:00Z"
}
]
}
}
}"""
jsonData = json.loads(data)
Races is an array, in this case there is only one race so you would desigate it as ["Races"][0]
print(jsonData["MRData"]["RaceTable"]["Races"][0]["time"])
data['time'] would work if you had a flat dictionary, but you have a nested dicts/list structure, so:
data["MRData"]["RaceTable"]["Races"][0]["time"]
data["MRData"] returns another dict, which has a key "RaceTable". The value of this key is again a dictionary which has a key "Races". The value of this is a list of races, of which you only have one. The races are again dicts which have the key time.
I have a JSON object which I want to flatten before exporting it to CSV. I'd like to use the flatten_json module for this.
My JSON input looks like this:
{
"responseStatus": "SUCCESS",
"responseDetails": {
"total": 5754
},
"data": [
{
"id": 1324651
},
{
"id": 5686131
},
{
"id": 2165735
},
{
"id": 2133256
}
]
}
Easy so far even for a beginner like me, but what I'm interesting in exporting is only the data array. So, I would think of this:
data_json = json["data"]
flat_json = flatten_json.flatten(data_json)
Which doesn't work, since data is an array, stored as a list in Python, not as a dictionary:
[
{
"id": 1324651
},
{
"id": 5686131
},
{
"id": 2165735
},
{
"id": 2133256
}
]
How should I proceed to feed the content of the data array into the flatten_json function?
Thanks!
R.
This function expects a ditionary, let's pass one:
flat_json = flatten_json.flatten({'data': data_json})
Output:
{'data_0_id': 1324651, 'data_1_id': 5686131, 'data_2_id': 2165735, 'data_3_id': 2133256}
You can choose the keys you want to ignore when you call the flatten method. For example, in your case, you can do the following.
flatten_json.flatten(dic, root_keys_to_ignore={'responseStatus', 'responseDetails'})
where dic is the original JSON input.
This will give as output:
{'data_0_id': 1324651, 'data_1_id': 5686131, 'data_2_id': 2165735, 'data_3_id': 2133256}
The workplace api returns a json response:
{
"name": "AA",
"owner": {
"name": "ser1",
"id": "1234"
},
"id": "567",
"admins": {
"data": [
{
"name": "codez",
"id": "457"
},
],
"paging": {
"cursors": {
"before": "qwrqwreqreqr",
"after": "teyryryryr"
}
}
}
I access the json response in python using the below for loop:
for item in feed:
row = [item["name"],item["id"], item["email"], item["privacy"],item["updated_time"],item["admins"]["data"]["name"]]
I get the error "list indices must be integers or slices, not list". When I remove the item["admins"]["data"]["name"], I don't get the error message.
Any suggestions would be appreciated !!
You need to access list. The data node contains a list so you need to access index 0 then access the key value pair.
for item in feed:
row = [item["name"],item["id"], item["email"], item["privacy"],item["updated_time"],item["admins"]["data"][0]["name"]]
data maps to a list with size one so you could do item["admins"]["data"][0]["name"]
Although this could be done much easier with row = item.values()
I would like to make the following JSON syntax output with python:
data={
"timestamp": "1462868427",
"sites": [
{
"name": "SiteA",
"zone": 1
},
{
"name": "SiteB",
"zone": 7
}
]
}
But I cannot manage to get the 'outer' data key there.
So far I got this output without the data key:
{
"timestamp": "1462868427",
"sites": [
{
"name": "SiteA",
"zone": 1
},
{
"name": "SiteB",
"zone": 7
}
]
}
I have tried with this python code:
sites = [
{
"name":"nameA",
"zone":123
},
{
"name":"nameB",
"zone":324
}
]
data = {
"timestamp": 123456567,
"sites": sites
}
print(json.dumps(data, indent = 4))
But how do I manage to get the outer 'data' key there?
Once you have your data ready, you can simply do this :
data = {'data': data}
JSON doesn't have =, it's all key:value.
What you're looking for is
data = {
"data": {
"timestamp": 123456567,
"sites": sites
}
}
json.dumps(data)
json.dumps() doesn't care for the name you give to the data object in python. You have to specify it manually inside the object, as a string.