Load pretty printed JSON from file into python? - python

I have a large JSON document stored in a pretty-print format to file, where the file looks like:
$ nano data.json
{
"type" : "object",
"properties" : {
"price" : {"type" : "number"},
"name" : {"type" : "string"},
},
}
The traditional ways I've found for reading such json files, such as...
with open('data.json', 'r') as handle:
data = json.load(handle)
and...
json_data=open('data.json','r')
data = json.load(json_data)
json_data.close()
and...
data = []
with open('data.json') as f:
for line in f:
data.append(json.loads(line))
and...
ss = ''
with open('data.json', 'r') as f:
for line in f:
ss += ''.join(line.strip())
data = json.loads(ss.decode("utf-8","replace"))
...seem to only work for single-string, not pretty-print formatted JSON.
How would I load JSON of this format from a file? The errors I keep getting when trying these formats are...
Traceback (most recent call last):
File "<stdin>", line 7, in <module>
File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting , delimiter: line 1 column 250 (char 250)
ValueError: Expecting , delimiter: line 9 column 13 (char 310)

For anyone else finding this in the future googling things similar to what I did when I posted this---you may think your error is in the loading, but mine as above was actually in the JSON itself, rather than the loading (as Martijn Pieters pointed out). I was copying the schema from the jsonschema python project---but this, it turned out, was not JSON, but a deceptively similar-looking python dictionary.

Related

Json file cant be edited

I want to append the brightness 0 to all lamps in list to a empty json file.
def first_start(lamps:list):
for lamp in lamps:
dict = {"light": {lamp: {"brightness": 0}}}
with open("data.json", "r") as file:
data = json.load(file)
data.update(dict)
print(dict)
with open("data.json", 'w') as file:
json.dump(data, file)
Everytime I run this code, I get this error:
Traceback (most recent call last):
File "C:\Users\brend\PycharmProjects\Hue_Control\main.py", line 27, in <module>
first_start(lamps)
File "C:\Users\brend\PycharmProjects\Hue_Control\main.py", line 16, in first_start
data = json.load(file)
File "C:\Users\brend\AppData\Local\Programs\Python\Python39\lib\json\__init__.py", line 293, in load
return loads(fp.read(),
File "C:\Users\brend\AppData\Local\Programs\Python\Python39\lib\json\__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "C:\Users\brend\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\brend\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Could somebody please help me, what im doing wrong?
Thank you :)
There is no such thing as an empty json file. If you have an empty file, then its not a json file.
You could ignore all the errors and assume that the file should contain "{}" and carry on:
def first_start(lamps:list):
for lamp in lamps:
upd = {"light": {lamp: {"brightness": 0}}}
data = {} # Empty dict just in case
try:
with open("data.json", "r") as file:
data = json.load(file)
except Exception:
print('Ignore errors with data.json')
data.update(upd)
with open("data.json", 'w') as file:
json.dump(data, file)

Cannot load a JSON file I just created (json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0))

I'm trying to work with json files, but I'm unable to load the file I just saved.
time_vals = { "seconds": time_spent, "day": amnt}
json_o = json.dumps(time_vals, indent = 4)
with open(os.path.join(os.getcwd(), fname + ".json",), 'a+') as f:
loaded = json.loads(f.read()) <- error
f.write(json_o)
I'm not sure what I'm doing wrong. I tried json.loads(f.read().decode('UTF-8')) and json.load(f) and they both give me errors as well.
Edit:
The purpose of this code is to store time spent on something as a json, and if the time exceeds a certain amount add something else (that's why I'm trying to load the file, to attempt to get the int values stored)
Traceback when using json.load(f):
Traceback (most recent call last):
File "C:\Users\julkt\PycharmProjects\pythonProject\venv\lib\site-packages\flask\app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\julkt\PycharmProjects\pythonProject\venv\lib\site-packages\flask\app.py", line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\julkt\PycharmProjects\pythonProject\venv\lib\site-packages\flask\app.py", line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\julkt\PycharmProjects\pythonProject\venv\lib\site-packages\flask\app.py", line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:/Users/julkt/Documents/Python_projectaaaaaaaaaaaaas/GUI project/guiproject.py", line 346, in send_url
loaded = json.load(f)
File "C:\Users\julkt\AppData\Local\Programs\Python\Python38\lib\json\__init__.py", line 293, in load
return loads(fp.read(),
File "C:\Users\julkt\AppData\Local\Programs\Python\Python38\lib\json\__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "C:\Users\julkt\AppData\Local\Programs\Python\Python38\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\julkt\AppData\Local\Programs\Python\Python38\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
192.168.1.162 - - [16/Sep/2021 18:01:25] "POST /send_url HTTP/1.1" 500 -
When you open a file "a+" (append plus read), the file pointer is set at the end of file, ready for the next write to append data. when you read, its already at EOF so you get the empty string "". Its the same as if you had witten
json.loads("")
Its hard to manage a file for writing and reading, especially with python where an intermediate encoder/decoder for bytes to str translation may be caching data. There are other details to consider such as flushing data to make sure its really available for a read.
Better to segment your code to reading bits and writing bits, and close the file in between. To get the same sequence you've shown, you could
import json
time_vals = { "seconds": 20, "day": 44}
# load records
try:
with open("test.json") as f:
records = [json.loads(line) for line in f]
print("records", records)
except OSError:
print("no records")
# append new record
with open("test.json", "a") as f:
print(json.dumps(time_vals), file=f) # print record with newline
Running multiple times I get
td:~/tmp/e$ python3 test.py
records [{'seconds': 20, 'day': 44}]
td:~/tmp/e$ python3 test.py
records [{'seconds': 20, 'day': 44}, {'seconds': 20, 'day': 44}]
td:~/tmp/e$ python3 test.py
records [{'seconds': 20, 'day': 44}, {'seconds': 20, 'day': 44}, {'seconds': 20, 'day': 44}]
Have you tried to open the JSON with something like jsonvier to see if the JSON is properly constructed? Could be some indentation problems or similar maybe
Use json.load() for file instead of json.loads() used for strings.
From the documentation:
json.load(): Deserialize fp (a .read()-supporting text file or binary file containing a JSON document) to a Python object using this conversion table.
json.loads(): Deserialize s (a str, bytes or bytearray instance containing a JSON document) to a Python object using this conversion table.
You can split your actions in two way. First retrieve the JSON content from your file:
with open(os.path.join(os.getcwd(), fname + ".json")) as f:
loaded = json.load(f)
# do your stuff with the loaded obj
Then write your new JSON to your file with json.dump():
with open(os.path.join(os.getcwd(), fname + ".json"), 'w') as outfile:
json.dump(loaded, outfile)
When you open the file with mode "a+", you can read or write but the main idea is "append": the file pointer is placed at the end of the file, so there is nothing to read there!
Keep it simple, open the file separately for reading and writing, and you should be all right.
with open(fname + ".json", 'r') as f:
loaded = json.load(f)
...
with open(fname + ".json", 'w') as f:
...

JSON decode error while loading of json files

The json module is not loading the json file. I have provided the correct path of the json file and i am just loading the file and trying to print it however it just is showing this error and i am not able to find a way around.
import json
f = open('test.json', 'r')
json.load(f)
f.close()
The error output is :
Traceback (most recent call last):
File "C:/Users/DELL/PycharmProjects/helloworld/Data_project/Sort_user.py", line 10, in <module>
json.load(f)
File "C:\Program Files\Python37\lib\json\__init__.py", line 296, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "C:\Program Files\Python37\lib\json\__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "C:\Program Files\Python37\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Program Files\Python37\lib\json\decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
The file starts with { and has '' for values.It has many values and large in size.
Dummy type:
{'abc': 'abc', 'abc': 2, 'abc': 123123, 'abc': 21, 'abc': 'abc', 'abc': 'abc'}
like this many more rows
json.load expects double quotes for property names e.g.:
[{"name":"John Doe","value":1},{"name":"John Snow","value":2}]
Also, ensure that any boolean values (TRUE, FALSE) are in lower case (true, false)
You should check following too:
Expecting double quotes - 1
Expecting double quotes - 2
and importantly this : single-vs-double-quotes-in-json

How do I give a JSON string object an attribute to read?

I'm trying to use JSON to select objects from a list, then delete those objects once they've been selected. I keep running into errors telling me
AttributeError: 'str' object has no attribute 'read'
path_album_list = 'C:\\Users\\steve\\AppData\\Local\\Programs\\Python\\Python36\\albums.json'
albums = json.load(path_album_list)
album = random.choice(albums)
print ('Today\'s soundtrack is "%s."' % album)
albums.remove(album)
json.dump(albums, path_album_list)
I also tried using json.loads, but then I got even more errors:
Traceback (most recent call last):
File "C:\Users\steve\AppData\Local\Programs\Python\Python36\randomizer.py", line 20, in <module>
albums = json.loads(path_album_list)
File "C:\Users\steve\AppData\Local\Programs\Python\Python36\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "C:\Users\steve\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\steve\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)*
json.load takes a file object, not a string. So you need to do this:
path_album_list = 'C:\\Users\\steve\\AppData\\Local\\Programs\\Python\\Python36\\albums.json'
jsonfile = open(path_album_list, "r")
albums = json.load(jsonfile)
jsonfile.close()
# ...
jsonfile = open(path_album_list, "w")
json.dump(albums, jsonfile)
jsonfile.close()
Or, you can use with statements, but the above is probably easier to understand.
path_album_list = 'C:\\Users\\steve\\AppData\\Local\\Programs\\Python\\Python36\\albums.json'
with open(path_album_list, "r") as jsonfile:
albums = json.load(jsonfile)
# ...
with open(path_album_list, "w") as jsonfile:
json.dump(albums, jsonfile)
The reason you need to open the files is that json interacts with files, not with strings of the file path.

I can't parse a json file with python

first post here.
I've been using Python for a while now, but I'm stuck with a very simple case.
I just want to parse a JSON file with simplejson module: here is the code:
import simplejson
with open('myjsontest.json', 'r') as data_file:
print data_file.read()
session = simplejson.load(data_file, strict=False)
And here is the JSON file named myjsontest.json:
[
{
"Test1": 1,
"Test2": 2,
"Test3": 3,
"Test4": 4
}
]
The JSON file is in the same folder as the python file.
I got this as a result:
[
{
"Test1": 1,
"Test2": 2,
"Test3": 3,
"Test4": 4
}
]
Traceback (most recent call last):
File ".\test.py", line 8, in <module>
session = simplejson.load(data_file, strict=False)
File "C:\Users\Gordon\Anaconda2\lib\site-packages\simplejson-3.8.1-py2.7.egg\simplejson\__init__.py", line 459, in loa
d
use_decimal=use_decimal, **kw)
File "C:\Users\Gordon\Anaconda2\lib\site-packages\simplejson-3.8.1-py2.7.egg\simplejson\__init__.py", line 533, in loa
ds
return cls(encoding=encoding, **kw).decode(s)
File "C:\Users\Gordon\Anaconda2\lib\site-packages\simplejson-3.8.1-py2.7.egg\simplejson\decoder.py", line 370, in deco
de
obj, end = self.raw_decode(s)
File "C:\Users\Gordon\Anaconda2\lib\site-packages\simplejson-3.8.1-py2.7.egg\simplejson\decoder.py", line 400, in raw_
decode
return self.scan_once(s, idx=_w(s, idx).end())
File "C:\Users\Gordon\Anaconda2\lib\site-packages\simplejson-3.8.1-py2.7.egg\simplejson\scanner.py", line 127, in scan
_once
return _scan_once(string, idx)
File "C:\Users\Gordon\Anaconda2\lib\site-packages\simplejson-3.8.1-py2.7.egg\simplejson\scanner.py", line 87, in _scan
_once
raise JSONDecodeError(errmsg, string, idx)
simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
I think think I may have a problem in my OS/python setup? Python 32b 2.7.11 is installed with Anaconda on a Windows7 64b.
Thanks if you can help.
Once you read a file, its stream is at the end and cannot be read from anymore. Your code should work if you remove the print data_file.read() statement, or you .seek() back to the beginning of the file afterwards.

Categories