I am trying to read a JSON file which contains just an object with one property which is the index. That is successful but when i try to rewrite to the same JSON file i get an error.
The code is bellow :
import sys
import json
import os
import os.path
import json
try:
json_path = path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'indexes', 'table_index.json')
with open(json_path) as json_file:
data = json.load(json_file)
index1 = 4
data["index"] = index1
print(type(data)) #Prints 'dict'
with open((json_path), 'wb') as f:
json.dump(data, f)
except Exception as e:
print(e)
The error i get is
'str' object has no attribute 'dump'
What i am basically trying to achieve is read the JSON, change the index property to a different value and at the end rewrite to the same JSON file.
Printing data["index"] before writing gives the correct value of 4.
As discussed in the comments, the most likely reason is that you define somewhere in your code a variable called json which shadows the module name. For example,
import json
json_string = '{"something": 4}'
print(json.dumps(json_string)) # prints "{\"something\": 4}"
If you, however, make an assignment like this:
json = '{"something_else": 4}'
and then call the same command as above
print(json.dumps(json_string))
it will raise
AttributeError: 'str' object has no attribute 'dumps'
So, all you have to do is to check in your code whether you made an assignment like this, change it and the issue should be resolved.
Related
Json file example = {"process":[{"id":0,"path":"xyz"}, {"id":1,"path":"abc"}]}
with open(process_details.json,"r") as jsonfile:
write_data= json.load(jsonfile)
for processdetails in write_data['process']:
Path = function_to_retreive_path(processdetails['id'])
Write_data[processdetails]['path'] = Path
with open("process_details.json","w") as outfile:
json.dump(write_data,outfile)
As I'm trying to update the path for each process I'm able to retrieve the path but I'm unable to update it in process_details.json file. Getting the following error as unhashable type:'dict'
Can anyone advise me on this issue
Try this:
import json
def function_to_retreive_path (id):
return str (id) + "_updated"
with open("process_details.json","r") as f:
write_data = json.load(f)
for processdetails in write_data['process']:
# debug
print (processdetails)
print (processdetails['id'])
print (processdetails['path'])
# change value
path = function_to_retreive_path (processdetails['id'])
processdetails['path'] = path
# debug
print (processdetails['path'])
with open("process_details.json","w") as outfile:
json.dump(write_data,outfile)
Anyway, your error is caused by a typo. You are using Write_data with a capital W, so Python thinks, I don't know this variable, so it is no dictionary and thus not hashable.
I can't really answer because there are some missing functions in your code so I can't run it, but the error you are facing generally means that you are using a dictionary as a key in an other dictionary.
So I got this code that is supposed to sort a dictionary within a json file alphabetically by key:
import json
def values(infile,outfile):
with open(infile):
data=json.load(infile)
data=sorted(data)
with open(outfile,"w"):
json.dump(outfile,data)
values("values.json","values_out.json")
And when I run it I get this error:
AttributeError: 'str' object has no attribute 'read'
I'm pretty sure I messed something up when I made the function but I don't know what.
EDIT: This is what the json file contains:
{"two": 2,"one": 1,"three": 3}
You are using the strings infile and outfile in your json calls, you need to use the file description instance, that you get using as keyword
def values(infile,outfile):
with open(infile) as fic_in:
data = json.load(fic_in)
data = sorted(data)
with open(outfile,"w") as fic_out:
json.dump(data, fic_out)
You can group, with statements
def values(infile, outfile):
with open(infile) as fic_in, open(outfile, "w") as fic_out:
json.dump(sorted(json.load(fic_in)), fic_out)
You forgot to assign the file you opened to a variable. In your current code you open a file, but then try to load the filename rather than the actual file. This code should run because you assign the file object reference to my_file.
import json
def values(infile,outfile):
with open(infile) as my_file:
data=json.load(my_file)
data=sorted(data)
with open(outfile,"w"):
json.dump(outfile,data)
values("values.json","values_out.json")
I'm creating two files using python script, first file is JSON and second one is HTML file, my below is creating json file but while creating HTML file I'm getting error. Could someone help me to resolve the issue? I'm new to Python script so it would be really appreciated if you could suggest some solution
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import json
JsonResponse = '[{"status": "active", "due_date": null, "group": "later", "task_id": 73286}]'
def create(JsonResponse):
print JsonResponse
print 'creating new file'
try:
jsonFile = 'testFile.json'
file = open(jsonFile, 'w')
file.write(JsonResponse)
file.close()
with open('testFile.json') as json_data:
infoFromJson = json.load(json_data)
print infoFromJson
htmlReportFile = 'Report.html'
htmlfile = open(htmlReportFile, 'w')
htmlfile.write(infoFromJson)
htmlfile.close()
except:
print 'error occured'
sys.exit(0)
create(JsonResponse)
I used below online Python editor to execute my code:
https://www.tutorialspoint.com/execute_python_online.php
infoFromJson = json.load(json_data)
Here, json.load() will expect a valid json data as json_data. But the json_data you provided are not valid json, it's a simple string(Hello World!). So, you are getting the error.
ValueError: No JSON object could be decoded
Update:
In your code you should get the error:
TypeError: expected a character buffer object
That's because, the content you are writing to the file needs to be string, but in place of that, you have a list of dictionary.
Two way to solve this. Replace the line:
htmlfile.write(infoFromJson)
To either this:
htmlfile.write(str(infoFromJson))
To make infoFromJson a string.
Or use the dump utility of json module:
json.dump(infoFromJson, json_data)
If you delete Try...except statement, you will see errors below:
Traceback (most recent call last):
File "/Volumes/Ithink/wechatProjects/django_wx_joyme/app/test.py", line 26, in <module>
create(JsonResponse)
File "/Volumes/Ithink/wechatProjects/django_wx_joyme/app/test.py", line 22, in create
htmlfile.write(infoFromJson)
TypeError: expected a string or other character buffer object
Errors occurred because htmlfile.write need string type ,but infoFromJson is a list .
So,change htmlfile.write(infoFromJson) to htmlfile.write(str(infoFromJson)) will avoid errors!
I'm trying to create new json file with my custom json input and converting JSON to HTML format and saving into .html file. But I'm getting error while generating JSON and HTML file. Please find my below code - Not sure what I'm doing wrong here:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from json2html import *
import sys
import json
JsonResponse = {
"name": "json2html",
"description": "Converts JSON to HTML tabular representation"
}
def create(JsonResponse):
#print JsonResponse
print 'creating new file'
try:
jsonFile = 'testFile.json'
file = open(jsonFile, 'w')
file.write(JsonResponse)
file.close()
with open('testFile.json') as json_data:
infoFromJson = json.load(json_data)
scanOutput = json2html.convert(json=infoFromJson)
print scanOutput
htmlReportFile = 'Report.html'
htmlfile = open(htmlReportFile, 'w')
htmlfile.write(str(scanOutput))
htmlfile.close()
except:
print 'error occured'
sys.exit(0)
create(JsonResponse)
Can someone please help me resolve this issue.
Thanks!
First, get rid of your try / except. Using except without a type expression is almost always a bad idea. In this particular case, it prevented you from knowing what was actually wrong.
After we remove the bare except:, we get this useful error message:
Traceback (most recent call last):
File "x.py", line 31, in <module>
create(JsonResponse)
File "x.py", line 18, in create
file.write(JsonResponse)
TypeError: expected a character buffer object
Sure enough, JsonResponse isn't a character string (str), but is a dictionary. This is easy enough to fix:
file.write(json.dumps(JsonResponse))
Here is a create() subroutine with some other fixes I recommend. Note that writing the dumping the JSON followed immediately by loading the JSON is usually silly. I left it in assuming that your actual program does something slightly different.
def create(JsonResponse):
jsonFile = 'testFile.json'
with open(jsonFile, 'w') as json_data:
json.dump(JsonResponse, json_data)
with open('testFile.json') as json_data:
infoFromJson = json.load(json_data)
scanOutput = json2html.convert(json=infoFromJson)
htmlReportFile = 'Report.html'
with open(htmlReportFile, 'w') as htmlfile:
htmlfile.write(str(scanOutput))
The error is while writing to the JSON file. Instead of file.write(JsonResponse) you should use json.dump(JsonResponse,file). It will work.
I've a simple question about file string manipulation.
I've written a bit of code that finally works other than for the final message. For the sake of my explanation, please have a look at a simplified version of my code below.
outStream = "/Users/andreamoro/Desktop/domains_output.csv"
try:
outStream = open(outStream, "w")
...
do something
except:
....
else:
print "A new output file %s has been created." %os.path.basename(outStream)
my desired output should be just the filename ... instead I get an exception like this
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.py", line 121, in basename
i = p.rfind('/') + 1
AttributeError: 'file' object has no attribute 'rfind'
I'm certainly using the wrong method, and I cannot expect to cast a file type into a string. I'm surprised there is not a method to return just the file name, and if it exist I wasn't able to find it.
Can you please point in the right direction?
Thanks
The problem in your code is that you re-assigned outStream to a file object.
outStream = "/Users/andreamoro/Desktop/domains_output.csv"
try:
outStream = open(outStream, "w") # now outStream is this
Rename either the string object or the file object and your code will work fine.
Otherwise it works fine:
>>> strs = "/Users/andreamoro/Desktop/domains_output.csv"
>>> os.path.basename(strs)
'domains_output.csv'
outStream variable is reassigned and becomes a file-like object:
outStream = open(outStream, "w")
Now you can get the name of the file from outStream.name:
name
If the file object was created using open(), the name of the
file. Otherwise, some string that indicates the source of the file
object, of the form "<...>". This is a read-only attribute and may not
be present on all file-like objects.
(docs)
os.path.basename(outStream.name) # is equal to 'domains_output.csv'