python3 How to read json file, modify and write? - python

I am trying to read a json file, modify and then save the modified version.
Unfortunately, the content of the file, instead of being saved, adds another json to the end of the original one.
my code:
with open(os.environ.get("WORKSPACE")+"/test.json", 'r+') as test_file:
test = json.load(test_file)
test['COMPONENTS'] = "test components"
json.dump(test, test_file)
test.json
{"STAGE": "Test", "DATE": "2023-02-17", "TIME": "13:27", "COMPONENTS": ""}
after running code
{"STAGE": "Test", "DATE": "2023-02-17", "TIME": "13:27", "COMPONENTS": ""}{"STAGE": "Test", "DATE": "2023-02-17", "TIME": "13:27", "COMPONENTS": "test components"}
expected result:
{"STAGE": "Test", "DATE": "2023-02-17", "TIME": "13:27", "COMPONENTS": "test components"}
Please point out what I am doing wrong
My environment
Python 3.10.9
macos 12.3.1
I try to use w+
Exception has occurred: JSONDecodeError
Expecting value: line 1 column 1 (char 0)
StopIteration: 0
During handling of the above exception, another exception occurred:
File "/test.py", line 20, in <module>
test = json.load(test_file)
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

The easiest way to do it, like UpmostScarab said, is to just open the file twice. If you only want to open it once for some reason, you can read, then seek(0), then write, and finally truncate:
with open(os.environ.get("WORKSPACE")+"/test.json", 'r+') as test_file:
test = json.load(test_file)
test['COMPONENTS'] = "test components"
test_file.seek(0)
json.dump(test, test_file)
test_file.truncate()

I think the problem is adding a + to your opening modes. Also note that w+ would truncate the file, so there will be no JSON to read. I think what you should do is:
with open(os.environ.get("WORKSPACE")+"/test.json", 'r') as test_file:
test = json.load(test_file)
test['COMPONENTS'] = "test components"
with open(os.environ.get("WORKSPACE")+"/test.json", 'w') as test_file:
json.dump(test, test_file)

Related

How to get string of JSON settings in Python

I'm new to python and still I love it but this makes me really frustrated.
I'm trying to load 4 settings in my console app since Write.Input causing errors when converting .exe file, so I was thinking instead let user type and hit enter it would be wise to load some .JSON settings file.
I need to get all values from "amount"; "threads" etc...
My Json settings file settings.json
{ "settings_data":[
{
"amount": 1000,
"threads": 5,
"type": 1,
"id": "sK19"
}
]}
My Code:
with open(os.path.join(sys.path[0], "settings.json"), "r", encoding="utf-8") as f:
settings = json.loads(f.read())
sendTypeA = json.dumps(settings)
sendTypeB = json.loads(sendTypeA)
sendType = sendTypeB["type"]
ERROR:
Exception has occurred: KeyError
'type'
File "D:\pyprograms\main\main.py", line 38, in <module>
sendType = sendTypeB["type"]
Try the following code:
with open(os.path.join(sys.path[0], "settings.json"), "r", encoding="utf-8") as f:
settings = json.loads(f.read())
sendType = settings["settings_data"][0]["type"]
Instead of:
sendType = sendTypeB["type"]
...you need...
sendType = sendTypeB["settings_data"][0]["type"]
...because the "type" key is in a dictionary that's in the first element of the list referred to by sendTypeB["settings_data"]

How to read multiple JSON objects in a single file?

I want to read multiple JSON objects from a single file imported from local dir. So far this is my simple work:
Data:
[{
"uuid": "6f476e26",
"created": "2018-09-26T06:57:04.142232",
"creator": "admin"
}, {
"uuid": "11d1e78a",
"created": "2019-09-21T11:19:39.845876",
"creator": "admin"
}]
Code:
import json
with open('/home/data.json') as f:
for line in f:
data = json.load(f)
Error:
File "/usr/lib64/python3.8/json/decoder.py", line 340, in decode
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 8 (char 7)
My question is similar to Loading and parsing a JSON file with multiple JSON objects and I've tried it however same issue appears. What should I do to solve this issue?
for line in f:
data = json.load(f)
This makes no sense. You are trying to parse the file over and over again, as many times as the number of lines in the file. This is more problematic than it sounds since f is exhausted after the first call to json.load(f).
You don't need the loop, just pass f to json.load:
with open('/home/data.json') as f:
data = json.load(f)
print(data)
outputs
[{'uuid': '6f476e26', 'created': '2018-09-26T06:57:04.142232', 'creator': 'admin'},
{'uuid': '11d1e78a', 'created': '2019-09-21T11:19:39.845876', 'creator': 'admin'}]
Now you can loop over data or directly access a specific index, ie data[0] or data[1].

JSON in Python error: json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

I am trying to extract text from a JSON file in python, but I am receiving the following error:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
The code I am trying to run:
import json
with open('file.json', encoding="utf-8") as json_file:
thing = json.load(json_file)
print(thing['text'])
The JSON file: (a shortened example of what I'm using)
{
"resources": "https://www.example.com",
"id": 1,
"joined": [],
"text": "Hello.\n The dog sat. \n\n The cat ran",
"urls": [
"https://www.example.com",
"https://www.example.com",
"https://www.example.com"
]
}
I would appreciate any suggestions for how to solve this error. (I've seen a few similar questions, but they seem to deal with API issues. Apologies if I'm missing something!)
(I am new to stack overflow and JSON, so I sincerely apologize if this is not a good question!)
I received an error concerning control characters. This was solved with double slashes.
Try this code:
ss = '''
{
"resources": "https://www.example.com",
"id": 1,
"joined": [],
"text": "Hello.\\n The dog sat. \\n\\n The cat ran",
"urls": [
"https://www.example.com",
"https://www.example.com",
"https://www.example.com"
]
}
'''.strip()
with open('file.json','w') as f: f.write(ss) # write test file
#####################
import json
with open('file.json', encoding="utf-8") as json_file:
thing = json.load(json_file)
print(thing['text'])
Output
Hello.
The dog sat.
The cat ran

KeyError occures while opening the JSON txt file and setting it up into a DataFrame

I had a code, which gave me an empty DataFrame with no saved tweets.
I tried to debug it by putting print(line) under the for line in json file: and json_data = json.loads(line).
That resulted a KeyError.
How do I fix it?
Thank you.
list_df = list()
# read the .txt file, line by line, and append the json data in each line to the list
with open('tweet_json.txt', 'r') as json_file:
for line in json_file:
print(line)
json_data = json.loads(line)
print(line)
tweet_id = json_data['tweet_id']
fvrt_count = json_data['favorite_count']
rtwt_count = json_data['retweet_count']
list_df.append({'tweet_id': tweet_id,
'favorite_count': fvrt_count,
'retweet_count': rtwt_count})
# create a pandas DataFrame using the list
df = pd.DataFrame(list_df, columns = ['tweet_id', 'favorite_count', 'retweet_count'])
df.head()
Your comment says you're trying to save to a file, but your code kind of says that you're trying to read from a file. Here are examples of how to do both:
Writing to JSON
import json
import pandas as pd
content = { # This just dummy data, in the form of a dictionary
"tweet1": {
"id": 1,
"msg": "Yay, first!"
},
"tweet2": {
"id": 2,
"msg": "I'm always second :("
}
}
# Write it to a file called "tweet_json.txt" in JSON
with open("tweet_json.txt", "w") as json_file:
json.dump(content, json_file, indent=4) # indent=4 is optional, it makes it easier to read
Note the w (as in write) in open("tweet_json.txt", "w"). You're using r (as in read), which doesn't give you permission to write anything. Also note the use of json.dump() rather than json.load(). We then get a file that looks like this:
$ cat tweet_json.txt
{
"tweet1": {
"id": 1,
"msg": "Yay, first!"
},
"tweet2": {
"id": 2,
"msg": "I'm always second :("
}
}
Reading from JSON
Let's read the file that we just wrote, using pandas read_json():
import pandas as pd
df = pd.read_json("tweet_json.txt")
print(df)
Output looks like this:
>>> df
tweet1 tweet2
id 1 2
msg Yay, first! I'm always second :(

Parsing file via 'iter' excludes a string

This is driving me crazy, help is appreciated. Here's what I'm trying to do:
With a JSON file as input, find two consecutive lines that look like:
{
"description"
Then, if that condition is found, insert additional JSON above this point. Following code almost works except that for some reason that I can't figure out, one line is getting skipped.
Code:
with open('file.in',encoding="utf8") as in_file:
with open('file.out','w',encoding="utf8") as out_file:
tag_to_check_line1 = '{'
tag_to_check_line2 = '"description"'
tag_to_check_not_line2 = ',"description"'
irofile = iter(in_file)
for line in irofile:
if tag_to_check_line1 in line:
out_file.write(line)
line = next(irofile)
if tag_to_check_line2 in line and tag_to_check_not_line2 not in line:
out_file.write('\n')
out_file.write('"fields": {\n')
out_file.write('"project":\n')
out_file.write('{\n')
out_file.write('"key": "GID"\n')
out_file.write('},\n')
out_file.write(line)
else:
out_file.write(line)
Input data looks like:
{
"description": "<p>The description is here.</p>",
"customfield_16818": "REQ-7591",
"customfield_16819": "GID-1214020",
"customfield_16815":{"self":"https://jira.com/rest/api/2/customFieldOption/20685","value":"No","id":"20685"},
"summary": "MySQL Redundancy",
"customfield_16816": "0",
"customfield_16817": "0",
"tag": "tagtext"
}
The resulting output looks right, except that the "summary" tag is missing:
{
"fields": {
"project":
{
"key": "GID"
},
"description": "<p>The description is here.</p>",
"customfield_16818": "REQ-7591",
"customfield_16819": "GID-1214020",
"customfield_16815":{"self":"https://jira.com/rest/api/2/customFieldOption/20685","value":"No","id":"20685"},
"customfield_16816": "0",
"customfield_16817": "0",
"tag": "tagtext"
}
So the question is: Why is the "summary" tag missing?
You're missing an else: clause. Can be fixed as indicated below:
with open('file.in',encoding="utf8") as in_file:
with open('file.out', 'w', encoding="utf8") as out_file:
tag_to_check_line1 = '{'
tag_to_check_line2 = '"description"'
tag_to_check_not_line2 = ',"description"'
irofile = iter(in_file)
for line in irofile:
if tag_to_check_line1 in line:
out_file.write(line)
line = next(irofile)
if tag_to_check_line2 in line and tag_to_check_not_line2 not in line:
out_file.write('\n')
out_file.write('"fields": {\n')
out_file.write('"project":\n')
out_file.write('{\n')
out_file.write('"key": "GID"\n')
out_file.write('},\n')
out_file.write(line)
else: # ADD THESE
out_file.write(line) # TWO LINES
else:
out_file.write(line)

Categories