Reputation: 3
I am new to Python and I am trying to build a simple REST api with flask. I do not understand why this results in an error:
boxes = {}
counter = 1
for box in ListOfBoxes:
boxes['boxes'][counter]['ID']= box.ID
boxes['boxes'][counter]['name']= box.name
boxes['boxes'][counter]['state']= box.state
boxes['boxes'][counter]['directory']= box.directory
boxes['boxes'][counter]['provider']= box.provider
counter +=1
return jsonify(boxes)
While this works:
boxes = {}
counter = 1
for box in ListOfBoxes:
boxes['boxes'] = {}
boxes['boxes'][counter] = []
boxes['boxes'][counter].append({'ID': box.ID, 'name':box.name, 'state': box.state, 'directory': box.directory, 'provider': box.provider})
counter +=1
return jsonify(boxes)
Error being:
File "./flask/app.py",
line 16, in get_boxes boxes['boxes'][counter]['ID']= box.ID KeyError: 'boxes'
When googling and stackoverflowing for answers, mostly the second piece of code is used. At least that's what I understand from it.
Upvotes: 0
Views: 137
Reputation: 24164
A simple way to implement a default tree is to use a defaultdict
:
from collections import defaultdict
def Tree():
return defaultdict(Tree)
Then:
boxes = Tree()
boxes['boxes'][5]['provider']= box.provider
Upvotes: 1
Reputation: 56687
In your first example, you are trying to access uninitialized values.
boxes = {}
counter = 1
for box in ListOfBoxes:
boxes['boxes'][counter]['ID']= box.ID
Here boxes
is an empty dict, but boxes['boxes']
does not exist yet, nor do any of the other levels you're trying to access.
The second example is illustrating how to initialize each new layer in your data structure, before attempting to use it.
# Create a new Dictionary, assign to a key in Dictionary 'boxes'
boxes['boxes'] = {}
# Create a new List, assign to a key in Dictionary we just created
boxes['boxes'][counter] = []
# Now that this List exists, we can use .append() to add to it
boxes['boxes'][counter].append({'ID': box.ID, 'name':box.name, 'state': box.state, 'directory': box.directory, 'provider': box.provider})
You received a KeyError
because you tried to access a dictionary key that did not yet exist: boxes['boxes']
was never initialized to have a value; therefore, it does not exist.
Upvotes: 0
Reputation: 477794
Well the problem is that boxes
does not contain a key 'boxes'
. Since you here **do not set boxes['boxes']
, but you get the element, and perform operations on that element.
A way to resolve it, is of course immediately insert an element with that key in the dictionary boxes
, so:
boxes = {'boxes':[]}
Nevertheless this is still not enough, since again you get boxes['boxes'][counter]
to perform operations on that object. So again, you will have to construct a dictionary.
You can however rewrite your code elegantly using list-comprehension and dictionary literals to:
result = [{'ID': box.ID,'name':box.name,'state':box.state,
'directory':box.directory,'provider':box.provider}
for box in ListOfBoxes]
boxes = {'boxes':result}
return jsonify(boxes)
If box
is an object and it contains only the fields discussed above, you can even use the following one-liner:
return jsonify({'boxes':[box.__dict__ for box in ListOfBoxes]})
since __dict__
is the dictionary of the object (containing the name of the fields mapped to its values). But this only works under the above discussed conditions.
Upvotes: 1