For loop only writes one object into a JSON file - python

I'm trying to iterate over a JSON file and write specific key values to a new JSON file:
def get_rubrik_failed_archives_main():
with open("get_failed_archives.json") as json_file:
json_data = json.load(json_file)
for archive_data in json_data["data"]:
dictionary = {
"objectName": archive_data["latestEvent"]["objectName"],
"time": archive_data["latestEvent"]["time"],
"eventType": archive_data["latestEvent"]["eventType"],
"eventStatus": archive_data["latestEvent"]["eventStatus"]
}
with open("rubrik_failed_archives.json", "w") as file:
json.dump(dictionary, file, indent=4, sort_keys=True)
The problem is that I cannot seem to write multiple objects into the JSON file, as I only get one object:
{
"eventStatus": "Failure",
"eventType": "Archive",
"objectName": "Template",
"time": "2022-08-21T16:09:31.863Z"
}
How do I write a for loop so that all of the needed key values get written into the new JSON file?

It appears that new data cannot be updated in dictionary.
So, The answer I came up with is json_data.update(dictionary)to add to the for loop.
def get_rubrik_failed_archives_main():
with open("get_failed_archives.json") as json_file:
json_data = json.load(json_file)
for archive_data in json_data["data"]:
dictionary = {
"objectName": archive_data["latestEvent"]["objectName"],
"time": archive_data["latestEvent"]["time"],
"eventType": archive_data["latestEvent"]["eventType"],
"eventStatus": archive_data["latestEvent"]["eventStatus"]
}
json_data.update(dictionary)
with open("rubrik_failed_archives.json", "w") as file:
json.dump(dictionary, file, indent=4, sort_keys=True)
I don't know if it will be solved because I can't check it, but I hope it helps you.

Related

Is there a way to return or get an output of JSON contents without using the print statement in Python?

Curious whether there's a way to return or output JSON contents into the terminal or somehow call them without using the print statement?
I'm writing a Python script to create a custom sensor in PRTG. The main goal of the script is to retrieve JSON data from Rubrik's API, extract specific key values from the JSON file and write them to a new JSON file. The contents of the second JSON file should be somehow outputted. PRTG requires not to use any sort of print statements in the script as it may corrupt the JSON.
I tried using various different methods, though did not find any success.
This is the code that I'm using:
import rubrik_cdm
import urllib3
import json
import sys
from datetime import datetime, timedelta
# Disable warnings
urllib3.disable_warnings()
# Authenticate by providing the node_ip and api_token
NODE_IP = ""
API_TOKEN = ""
# Establish a connection to Rubrik
rubrik = rubrik_cdm.Connect(
node_ip=NODE_IP,
api_token=API_TOKEN)
# Get Rubrik's failed archives from the past 24 hours and write them to a JSON file
def get_rubrik_failed_archives():
current_date = datetime.today() - timedelta(days=1) # <-- Get the datetime
datetime_to_string = current_date.strftime("%Y-%m-%dT%H:%M:%S")
get_failed_archives = rubrik.get("v1", f"/event/latest?event_status=Failure&event_type=Archive&before_date={datetime_to_string}&limit=1000")
with open("get_failed_archives.json", "w") as file:
json.dump(get_failed_archives, file, indent=3)
# Write first JSON file specific contents to a new JSON file
def get_rubrik_failed_archives_main():
with open("get_failed_archives.json") as json_file:
json_data = json.load(json_file)
failed_archives_data = []
for archive_data in json_data["data"]:
failed_archives_data.append({
"objectName": archive_data["latestEvent"]["objectName"],
"time": archive_data["latestEvent"]["time"],
"eventType": archive_data["latestEvent"]["eventType"],
"eventStatus": archive_data["latestEvent"]["eventStatus"],
})
with open("rubrik_failed_archives.json", "w") as file:
json.dump(failed_archives_data, file, indent=4, sort_keys=True)
return failed_archives_data
get_rubrik_failed_archives()
get_rubrik_failed_archives_main()
JSON file contents:
[
{
"eventStatus": "Failure",
"eventType": "Archive",
"objectName": "W12 BO Template",
"time": "2022-08-23T10:09:33.092Z"
},
{
"eventStatus": "Failure",
"eventType": "Archive",
"objectName": "W12 BO Template",
"time": "2022-08-23T09:06:33.786Z"
},
{
"eventStatus": "Failure",
"eventType": "Archive",
"objectName": "W12 BO Template",
"time": "2022-08-23T08:03:35.118Z"
},
{
"eventStatus": "Failure",
"eventType": "Archive",
"objectName": "W12 BO Template",
"time": "2022-08-23T07:00:32.683Z"
}
]
So, is there a way to return or get an output of JSON contents without using the print statement in Python?

Separate large JSON object into many different files

I have a JSON file with 10000 data entries like below in a file.
{
"1":{
"name":"0",
"description":"",
"image":""
},
"2":{
"name":"1",
"description":"",
"image":""
},
...
}
I need to write each entry in this object into its own file.
For example, the output of each file looks like this:
1.json
{
"name": "",
"description": "",
"image": ""
}
I have the following code, but I'm not sure how to proceed from here. Can anyone help with this?
import json
with open('sample.json', 'r') as openfile:
# Reading from json file
json_object = json.load(openfile)
You can use a for loop to iterate over all the fields in the outer object, and then create a new file for each inner object:
import json
with open('sample.json', 'r') as input_file:
json_object = json.load(input_file)
for key, value in json_object.items():
with open(f'{key}.json', 'w') as output_file:
json.dump(value, output_file)

How to get every value of a key of a JSON file with multiple dicts?

How to get every value of a key of a JSON file with multiple dicts? I want to extract every value of "username" key.
data.json
{
"1476439722046238725": {
"tweet_id": "1476439722046238725",
"username": "elonmusk",
},
"1476437555717541893": {
"tweet_id": "1476437555717541893",
"username": "billgate",
},
"1476437555717541893": {
"tweet_id": "1476437555717541893",
"username": "jeffbezos",
This is what my code so far but it gave me this error KeyError: 'username'.
main.py
import json
with open("data.json", "r") as f:
data = json.load(f)
print(data["username"])
You need to enumerate through the outer dictionary.
import json
with open("data.json", "r") as f:
data = json.load(f)
for val in data.values():
print( val['username'] )

How do I maintain the same structure when reading from, modifying and writing back to a JSON file?

I am currently reading in a JSON file, adding a key and writing it back out to the same file using this procedure
with open('data.json', 'r+') as f:
data = json.load(f)
temp_key={"test":"val"}
data["test"]["new_key"] = temp_key
f.seek(0) # <--- should reset file position to the beginning.
json.dump(data, f, indent=2)
f.truncate() # remove remaining part
(adopted from here)
but the issue is that it does not maintain order. for instance if I read in:
{
"test": {
"something": "something_else"
},
"abc": {
"what": "huh"
}
}
the output turns out as:
{
"abc": {
"what": "huh"
},
"test": {
"something": "something_else",
"new_key": {
"test": "val"
}
}
}
When I would like it to be:
{
"test": {
"something": "something_else",
"new_key": {
"test": "val"
}
},
"abc": {
"what": "huh"
}
}
I realise that JSON is a key/value based structure and the order does not matter, but is there a way of making the modification and maintaining the original structure?
As I said in a comment, you can use a collections.OrderedDict along with the optional object_pairs_hook keyword argument accepted by json.load() (in Python 2.7) to preserve the order of the original data when you rewrite the file.
This is what I meant:
#!/usr/bin/env python2
from collections import OrderedDict
import json
with open('ordered_data.json', 'r+') as f:
data = json.load(f, object_pairs_hook=OrderedDict)
temp_key = {"test": "val"}
data["test"]["new_key"] = temp_key
f.seek(0) # Reset file position to the beginning.
json.dump(data, f, indent=2)
f.truncate() # Remove remaining part.

Python JSON add Key-Value pair

I'm trying to add key value pairs into the existing JSON file. I am able to concatenate to the parent label, How to add value to the child items?
JSON file:
{
"students": [
{
"name": "Hendrick"
},
{
"name": "Mikey"
}
]
}
Code:
import json
with open("input.json") as json_file:
json_decoded = json.load(json_file)
json_decoded['country'] = 'UK'
with open("output.json", 'w') as json_file:
for d in json_decoded[students]:
json.dump(json_decoded, json_file)
Expected Results:
{
"students": [
{
"name": "Hendrick",
"country": "UK"
},
{
"name": "Mikey",
"country": "UK"
}
]
}
You can do the following in order to manipulate the dict the way you want:
for s in json_decoded['students']:
s['country'] = 'UK'
json_decoded['students'] is a list of dictionaries that you can simply iterate and update in a loop. Now you can dump the entire object:
with open("output.json", 'w') as json_file:
json.dump(json_decoded, json_file)
import json
with open("input.json", 'r') as json_file:
json_decoded = json.load(json_file)
for element in json_decoded['students']:
element['country'] = 'UK'
with open("output.json", 'w') as json_out_file:
json.dump(json_decoded, json_out_file)
opened a json file i.e. input.json
iterated through each of its element
add a key named "country" and dynamic value "UK", to each element
opened a new json file with the modified JSON.
Edit:
Moved writing to output file inside to first with segment. Issue with earlier implemenation is that json_decoded will not be instantiated if opening of input.json fails. And hence, writing to output will raise an exception - NameError: name 'json_decoded' is not defined
This gives [None, None] but update the dict:
a = {'students': [{'name': 'Hendrick'}, {'name': 'Mikey'}]}
[i.update({'country':'UK'}) for i in a['students']]
print(a)

Categories

Resources