Open shiihara0129 opened 5 years ago
Same problem, it seems to work better by replacing
return [x.attrib["id"] for x in row_tree]
with
return [x.attrib["id"] for x in row_tree if "id" in x.attrib]
I did a lot of debugging on this one and I disagree that there should be an "if" statement. Here are my observations:
The normally callable function update_spreadsheet_row()
runs into an error at this line:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/alexlazo/Packages/VMScripts/env/VMScripts-1.0/runtime/lib/python3.6/site-packages/quip.py", line 647, in get_row_ids
return [x.attrib["id"] for x in row_tree]
File "/home/alexlazo/Packages/VMScripts/env/VMScripts-1.0/runtime/lib/python3.6/site-packages/quip.py", line 647, in <listcomp>
return [x.attrib["id"] for x in row_tree]
KeyError: 'id'
The problematic function is:
def get_row_ids(self, row_tree):
"""Returns the ids of items in the given row `ElementTree`."""
return [x.attrib["id"] for x in row_tree]
The problem here is that when you create a list comprehension for a single item dictionary, Python seems to error out for some reason. I'm not sure why this design choice was made, as the get_row_ids()
function is only ever called in the update_spreadsheet_row()
function, which will only ever return a single ID.
For verification that this is problematic, I tried running each function one by one, trying to understand the issue. See below:
client = quip.QuipClient(...)
sheet = client.get_first_spreadsheet("XXXXXXXX")
row = client.find_row_from_header(sheet, "Rank1", "Acme2")
xmlrow = ET.tostring(row)
All of the above work as expected, I can find the sheet, row, and successfully see the XML raw output. However, when trying the following, you start seeing the errors:
>>> ids = client.get_row_ids(row)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/alexlazo/Packages/VMScripts/env/VMScripts-1.0/runtime/lib/python3.6/site-packages/quip.py", line 647, in get_row_ids
return [x.attrib["id"] for x in row_tree]
File "/home/alexlazo/Packages/VMScripts/env/VMScripts-1.0/runtime/lib/python3.6/site-packages/quip.py", line 647, in <listcomp>
return [x.attrib["id"] for x in row_tree]
KeyError: 'id'
Performing the call individually reveals the problem is with the list comprehension:
>>> type(row)
<class 'xml.etree.ElementTree.Element'>
>>> row.attrib["id"]
'XXXXXXXXXX'
>>> rowid = [x.attrib["id"] for x in row]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <listcomp>
KeyError: 'id'
>>> def call():
... return row.attrib["id"]
...
>>> call()
'XXXXXXXXXX'
My recommendation is one of the two following:
Let me know if you have any questions, spent quite a bit of time on this issue but it seems to boil down to the list comprehension bugging out on an object that returns a single item.
It fails to update one col ahead as section_id is referring based on index in a list of ids.
headers = self.get_spreadsheet_header_items(spreadsheet)
It receives, headers = [None, A,B,C] (so header includes columns for row number)
ids = self.get_row_ids(row)
it receives, ids=['s:xxxx','s:yyyy',s:zzzz'] (no id for row number col)
index = self.get_index_of_header(headers, "A")
index is "1" for col "A"
section_id=ids[index]
section_id become "s:yyyy" but actually we want to modify value for section id of 's:xxxx'
Assuming first column (where row number is shown) will have no id, section_id=ids[index-1] can be applied as workaround.
Or alternatively modify "get_spreadsheet_header_items" function to omit header if it's "None"
def get_row_ids(self, row_tree):
"""Returns the ids of items in the given row `ElementTree`."""
return [x.attrib.get("id", "") for x in row_tree]
This works for me for now.
It seems that the return value of API has been changed and
update_spreadsheet_row()
can not be used from 19/03/2019. This error occurs by this line. I tentatively changed to removed from therow_tree
those that do not have anid