Your shared citations Sheet has 80 rows. Each row has date, author, journal, and status columns. Before the lit-review meeting, you need the last 10 rows. In SPSS you'd open the file. In Python?
find_events from Day 11 fetched a list from Calendar. For Sheets, I'd expect GOOGLESHEETS_BATCH_GET with a sheet ID and a range like A1:D10 — the A1 notation I use in every Excel formula.
Exactly right. The range is in A1 notation — Sheet1!A1:D80 for the first 80 rows of columns A through D. The response nests the values inside a valueRanges key:
result = toolset.execute_action(
Action.GOOGLESHEETS_BATCH_GET,
{"spreadsheet_id": sheet_id, "ranges": [range_a1]}
)
rows = result.get("valueRanges", [{}])[0].get("values", [])Why result.get("valueRanges", [{}])[0].get("values", []) — that's two levels of .get(). Why the nested structure?
GOOGLESHEETS_BATCH_GET supports fetching multiple ranges in one call — that's what the "ranges" list allows. So the response wraps each range's values inside a valueRanges list, one entry per requested range. You requested one range, so you take [0] — the first (and only) entry — then get "values" from inside it. Two levels of nesting for one level of structure:
def read_range(sheet_id: str, range_a1: str) -> list:
result = toolset.execute_action(
Action.GOOGLESHEETS_BATCH_GET,
{"spreadsheet_id": sheet_id, "ranges": [range_a1]}
)
rows = result.get("valueRanges", [{}])[0].get("values", [])
print(f"Read {len(rows)} rows from {range_a1}")
return rowsSo a row in Sheets is just a list of strings? ["2026-04-12", "Smith 2024", "JPSP", "cited"]? That's the same list I used in the Python track.
The data structure you learned in Week 2, now backed by your real citation log.
A Sheets row is just a list of strings. I didn't expect to feel this level of relief at that sentence.
One detail: if a cell is empty, GOOGLESHEETS_BATCH_GET may omit it from the row list rather than returning an empty string. A row with 4 populated columns followed by empty columns might come back as 2 or 3 items. Use row[i] if i < len(row) else "" for safe field access by column index.
result = toolset.execute_action(
Action.GOOGLESHEETS_BATCH_GET,
{"spreadsheet_id": sheet_id, "ranges": ["Sheet1!A1:D80"]}
)
rows = result.get("valueRanges", [{}])[0].get("values", [])Sheet1!A1:D80 — sheet name + ! + column range + row range. If the sheet tab name has spaces: 'My Sheet'!A1:D80.
valueRanges is a list (one entry per requested range). Each entry has a values key with a list of row lists.
Empty trailing cells may be omitted. Use row[i] if i < len(row) else "" for safe column access.
Your shared citations Sheet has 80 rows. Each row has date, author, journal, and status columns. Before the lit-review meeting, you need the last 10 rows. In SPSS you'd open the file. In Python?
find_events from Day 11 fetched a list from Calendar. For Sheets, I'd expect GOOGLESHEETS_BATCH_GET with a sheet ID and a range like A1:D10 — the A1 notation I use in every Excel formula.
Exactly right. The range is in A1 notation — Sheet1!A1:D80 for the first 80 rows of columns A through D. The response nests the values inside a valueRanges key:
result = toolset.execute_action(
Action.GOOGLESHEETS_BATCH_GET,
{"spreadsheet_id": sheet_id, "ranges": [range_a1]}
)
rows = result.get("valueRanges", [{}])[0].get("values", [])Why result.get("valueRanges", [{}])[0].get("values", []) — that's two levels of .get(). Why the nested structure?
GOOGLESHEETS_BATCH_GET supports fetching multiple ranges in one call — that's what the "ranges" list allows. So the response wraps each range's values inside a valueRanges list, one entry per requested range. You requested one range, so you take [0] — the first (and only) entry — then get "values" from inside it. Two levels of nesting for one level of structure:
def read_range(sheet_id: str, range_a1: str) -> list:
result = toolset.execute_action(
Action.GOOGLESHEETS_BATCH_GET,
{"spreadsheet_id": sheet_id, "ranges": [range_a1]}
)
rows = result.get("valueRanges", [{}])[0].get("values", [])
print(f"Read {len(rows)} rows from {range_a1}")
return rowsSo a row in Sheets is just a list of strings? ["2026-04-12", "Smith 2024", "JPSP", "cited"]? That's the same list I used in the Python track.
The data structure you learned in Week 2, now backed by your real citation log.
A Sheets row is just a list of strings. I didn't expect to feel this level of relief at that sentence.
One detail: if a cell is empty, GOOGLESHEETS_BATCH_GET may omit it from the row list rather than returning an empty string. A row with 4 populated columns followed by empty columns might come back as 2 or 3 items. Use row[i] if i < len(row) else "" for safe field access by column index.
result = toolset.execute_action(
Action.GOOGLESHEETS_BATCH_GET,
{"spreadsheet_id": sheet_id, "ranges": ["Sheet1!A1:D80"]}
)
rows = result.get("valueRanges", [{}])[0].get("values", [])Sheet1!A1:D80 — sheet name + ! + column range + row range. If the sheet tab name has spaces: 'My Sheet'!A1:D80.
valueRanges is a list (one entry per requested range). Each entry has a values key with a list of row lists.
Empty trailing cells may be omitted. Use row[i] if i < len(row) else "" for safe column access.
Create a free account to get started. Paid plans unlock all tracks.