I'm getting the following error. I'm confident the error is due to my JSON formatting. How should I be formatting my JSON file?
Exception has occurred: AttributeError
'list' object has no attribute 'values'
The error is occurring on the following line
total_sites = len(custom_sites.values())
The function it's trying to execute
def get_available_websites():
string = []
with open('settings.json') as available_file:
for sites in json.load(available_file)['custom_sites']:
string.append(sites + ", ")
return (''.join(string))[:-2]
The JSON file
{
"custom_sites": [
"https://github.com",
"https://test.com"
]
}
I've tried various changes in the JSON file. Alternating [], and {}
custom_sites will be a list not a dict so it wont have a values attribute. you can just check the length of the list its self.
import json
json_str = """{
"custom_sites": [
"https://github.com",
"https://test.com"
]
}"""
custom_sites = json.loads(json_str)["custom_sites"]
total_sites = len(custom_sites)
print(f"{total_sites=}")
OUTPUT
total_sites=2
Related
This question already has answers here:
How can I parse (read) and use JSON?
(5 answers)
Closed 2 months ago.
I've already checked here and here.
I have the following json which has no root element and I want to loop through each item in objects and print the value for object_code:
{
"count": 3,
"objects": [
{
"object_code": "HN1059"
},
{
"object_code": "HN1060"
},
{
"object_code": "VO1013"
}
]
}
I tried:
json='{"count": 3,"objects": [{"object_code": "HN1059"},{"object_code": "HN1060"},{"object_code": "VO1013"}]}'
for obj in json['objects']:
print(obj.get('object_code'))
for obj in json[0]['objects']:
print(obj.get('object_code'))
Neither work and I get the error:
TypeError: string indices must be integers
UPDATE 1
The suggested solutions don't work for me, maybe that's because I'm using it in the context of a Scrapy class, here's the full code that throws error
TypeError: 'NoneType' object is not iterable
import json
import scrapy
class MySpider(scrapy.Spider):
name = 'mytest'
start_urls = []
def start_requests(self):
s='{"count": 3,"objects": [{"object_code": "HN1059"},{"object_code": "HN1060"},{"object_code": "VO1013"}]}'
obj = json.loads(s)
for o in obj['objects']:
print(o.get('object_code'))
You need to load fom the JSON content to python structure
import json
value = '{"count": 3,"objects": [{"object_code": "HN1059"},{"object_code": "HN1060"},{"object_code": "VO1013"}]}'
content = json.loads(value)
for obj in content['objects']:
print(obj.get('object_code'))
Use json.loads to convert the JSON string to a dict.
import json
s='{"count": 3,"objects": [{"object_code": "HN1059"},{"object_code": "HN1060"},{"object_code": "VO1013"}]}'
obj = json.loads(s)
for o in obj['objects']:
print(o.get('object_code'))
I have this method that writes json data to a file. The title is based on books and data is the book publisher,date,author, etc. The method works fine if I wanted to add one book.
Code
import json
def createJson(title,firstName,lastName,date,pageCount,publisher):
print "\n*** Inside createJson method for " + title + "***\n";
data = {}
data[title] = []
data[title].append({
'firstName:', firstName,
'lastName:', lastName,
'date:', date,
'pageCount:', pageCount,
'publisher:', publisher
})
with open('data.json','a') as outfile:
json.dump(data,outfile , default = set_default)
def set_default(obj):
if isinstance(obj,set):
return list(obj)
if __name__ == '__main__':
createJson("stephen-king-it","stephen","king","1971","233","Viking Press")
JSON File with one book/one method call
{
"stephen-king-it": [
["pageCount:233", "publisher:Viking Press", "firstName:stephen", "date:1971", "lastName:king"]
]
}
However if I call the method multiple times , thus adding more book data to the json file. The format is all wrong. For instance if I simply call the method twice with a main method of
if __name__ == '__main__':
createJson("stephen-king-it","stephen","king","1971","233","Viking Press")
createJson("william-golding-lord of the flies","william","golding","1944","134","Penguin Books")
My JSON file looks like
{
"stephen-king-it": [
["pageCount:233", "publisher:Viking Press", "firstName:stephen", "date:1971", "lastName:king"]
]
} {
"william-golding-lord of the flies": [
["pageCount:134", "publisher:Penguin Books", "firstName:william","lastName:golding", "date:1944"]
]
}
Which is obviously wrong. Is there a simple fix to edit my method to produce a correct JSON format? I look at many simple examples online on putting json data in python. But all of them gave me format errors when I checked on JSONLint.com . I have been racking my brain to fix this problem and editing the file to make it correct. However all my efforts were to no avail. Any help is appreciated. Thank you very much.
Simply appending new objects to your file doesn't create valid JSON. You need to add your new data inside the top-level object, then rewrite the entire file.
This should work:
def createJson(title,firstName,lastName,date,pageCount,publisher):
print "\n*** Inside createJson method for " + title + "***\n";
# Load any existing json data,
# or create an empty object if the file is not found,
# or is empty
try:
with open('data.json') as infile:
data = json.load(infile)
except FileNotFoundError:
data = {}
if not data:
data = {}
data[title] = []
data[title].append({
'firstName:', firstName,
'lastName:', lastName,
'date:', date,
'pageCount:', pageCount,
'publisher:', publisher
})
with open('data.json','w') as outfile:
json.dump(data,outfile , default = set_default)
A JSON can either be an array or a dictionary. In your case the JSON has two objects, one with the key stephen-king-it and another with william-golding-lord of the flies. Either of these on their own would be okay, but the way you combine them is invalid.
Using an array you could do this:
[
{ "stephen-king-it": [] },
{ "william-golding-lord of the flies": [] }
]
Or a dictionary style format (I would recommend this):
{
"stephen-king-it": [],
"william-golding-lord of the flies": []
}
Also the data you are appending looks like it should be formatted as key value pairs in a dictionary (which would be ideal). You need to change it to this:
data[title].append({
'firstName': firstName,
'lastName': lastName,
'date': date,
'pageCount': pageCount,
'publisher': publisher
})
Getting the following error for code that creates stored procedure activity for ADF V2.
Unable to build a model: Unable to deserialize response data. Data: {DateToImportFor :{value:2017-01-04,type:str}}, {StoredProcedureParameter}, AttributeError: 'str' object has no attribute 'items', DeserializationError: Unable to deserialize response data. Data: {DateToImportFor :{value:2017-01-04,type:str}}, {StoredProcedureParameter}, AttributeError: 'str' object has no attribute 'items'
My code:
spActivity_Name="AzureSQLDWStoredProcedureActivity"
storedproc_name ="DailyImport"
linkedService = LinkedServiceReference(lsdw)
p="{%s :{value:%s,type:str}}" % ('DateToImportFor','2017-01-04')
lsp_activity = SqlServerStoredProcedureActivity(name=spActivity_Name,
stored_procedure_name=storedproc_name,
stored_procedure_parameters=p,
linked_service_name=linkedService)
Since I am very new to python, I am not sure how to construct the parameters object.
#stored_procedure_parameter is expecting in the following format
:param stored_procedure_parameters: Value and type setting for stored
procedure parameters. Example: "{Parameter1: {value: "1", type: "int"}}".
:type stored_procedure_parameters: dict[str,
~azure.mgmt.datafactory.models.StoredProcedureParameter]
"""
p_name = 'StoredProcPipeLine'
params_for_pipeline = {}
p_obj = PipelineResource(activities=[lsp_activity], parameters=params_for_pipeline)
p = adf_client.pipelines.create_or_update(rg_name, df_name, p_name, p_obj)
Example on documentation is a little bit inaccurate, since it states the example for stored_procedure_parameters as a string.
Try setting p as a dictionary:
from azure.mgmt.datafactory.models import StoredProcedureParameter
p = {'DateToImportFor': StoredProcedureParameter('2017-01-04', type='String')}
This JSON to CSV code example is working great:
employee_data = '{"info":[{"employee_name": "James", "email": "james#gmail.com", "job_profile": "Sr. Developer"},{"employee_name": "Smith", "email": "Smith#gmail.com", "job_profile": "Project Lead"}]}'
#This can be parsed and converted to CSV using python as shown below:
import json
import csv
employee_parsed = json.loads(employee_data)
emp_data = employee_parsed['info']
# open a file for writing
employ_data = open('Employee.csv', 'w')
# create the csv writer object
csvwriter = csv.writer(employ_data)
count = 0
for emp in emp_data:
if count == 0:
header = emp.keys()
csvwriter.writerow([header])
count += 1
csvwriter.writerow([emp.values()])
employ_data.close()
My trouble comes in when I'm trying to use the following JSON data below...
I get an AttributeError: 'str' object has no attribute 'keys'. Please keep your response simple as this is my Python "Hello World". :-)
employee_data = '{"info": {"arch": "x86_64","platform": "linux"},"packages": {"_license-1.1-py27_0.tar.bz2": {"build": "py27_0","build_number": 0,"date": "2013-03-01","depends": ["python 2.7*"],"license": "proprietary - Continuum Analytics, Inc.","license_family": "Proprietary","md5": "5b13c8cd498ce15b76371ed85278e3a4","name": "_license","requires": [],"size": 194947,"version": "1.1"}}}'
Thank you for any direction on this.
The problem is that your code expects the JSON keys to be arrays. This loop here:
for emp in emp_data:
Expects each top level JSON key to be iterable (loopable). On your original JSON, the key info maps to a list:
[{"employee_name": "James", "email (...)
However, the ìnfo` key on the second JSON example does not map to a list but instead to a dictionary:
"info": {"arch": "x86_64","platform": "linux"}
Changing the info key to a list fixes it:
"info": [{"arch": "x86_64","platform": "linux"}]
In further depth, your emp_data variable looks like this:
{'platform': 'linux', 'arch': 'x86_64'}
And so when you iterate it (for emp in emp_data), emp will be "arch" or "platform", which you cannot get .keys() from.
With the following code below, There is an error saying
File "/home/user/web_pro/info/views.py", line 184, in headerview,
raise TypeError("%r is not JSON serializable" % (o,))
TypeError: <lastname: jerry> is not JSON serializable
In the models code
header(models.Model):
firstname = models.ForeignKey(Firstname)
lastname = models.ForeignKey(Lastname)
In the views code
headerview(request):
header = header.objects.filter(created_by=my_id).order_by(order_by)[offset:limit]
l_array = []
l_array_obj = []
for obj in header:
l_array_obj = [obj.title, obj.lastname ,obj.firstname ]
l_array.append(l_array_obj)
dictionary_l.update({'Data': l_array}) ;
return HttpResponse(simplejson.dumps(dictionary_l), mimetype='application/javascript')
what is this error and how to resolve this?
thanks..
The quick read is that obj.lastname is a Lastname model not a String. You probably need to say something like:
l_array_obj = [..., obj.lastname.value, .... ]
to get the string value, rather than the Model object.
Have you considered using Django's own serialization functionality?