find_events from Week 2 fetched structured data by ID and a parameter. The same shape applies to Sheets. GOOGLESHEETS_BATCH_GET takes a spreadsheet ID and an A1 range string — "A:D" means all rows in columns A through D.
My time log has four columns: date, client, hours, notes. A:D would get all of them.
Exactly. The response has a valueRanges key with a list of range objects. Each range has a values key containing a list of row lists — each inner list is one row of your spreadsheet:
result = toolset.execute_action(
Action.GOOGLESHEETS_BATCH_GET,
{"spreadsheet_id": sheet_id, "ranges": "A:D"}
)
ranges = result.get("valueRanges", [])
rows = ranges[0].get("values", []) if ranges else []
for row in rows:
print(row) # ['2026-04-12', 'Acme', '2.5', 'Review round 2']Wait — a row in my Sheet is just a Python list? Like ["2026-04-12", "Acme", "2.5", "Review round 2"]?
That is all it ever was. A list of strings. Now Python knows that too.
So I can filter rows by client name, sum the hours column, and build the time summary without opening the spreadsheet.
Filter, sum, format. The monthly time log becomes a function argument:
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}
)
ranges = result.get("valueRanges", [])
rows = ranges[0].get("values", []) if ranges else []
print(f"Read {len(rows)} rows from range {range_a1}")
return rowsMy time log is now a Python list. My accountant is going to be impressed.
All values come back as strings — even numbers. row[2] for hours is "2.5", not 2.5. Convert with float(row[2]) when you need to compute totals. The header row is always row rows[0] — skip it with rows[1:].
GOOGLESHEETS_BATCH_GET returns rows as a list of lists — each inner list is one row, each element is a cell value:
result = toolset.execute_action(
action=Action.GOOGLESHEETS_BATCH_GET,
params={'spreadsheetId': sheet_id, 'ranges': [range_a1]}
)
rows = result.get('valueRanges', [{}])[0].get('values', [])'A:D' means all rows in columns A through D. 'A1:D10' means the first 10 rows of those columns. The first row is usually the header.
Rows are lists of strings. Even numeric cells come back as strings — convert with float(row[2]) or int(row[2]) before doing arithmetic. Check len(row) before indexing to handle rows with fewer columns than expected.
find_events from Week 2 fetched structured data by ID and a parameter. The same shape applies to Sheets. GOOGLESHEETS_BATCH_GET takes a spreadsheet ID and an A1 range string — "A:D" means all rows in columns A through D.
My time log has four columns: date, client, hours, notes. A:D would get all of them.
Exactly. The response has a valueRanges key with a list of range objects. Each range has a values key containing a list of row lists — each inner list is one row of your spreadsheet:
result = toolset.execute_action(
Action.GOOGLESHEETS_BATCH_GET,
{"spreadsheet_id": sheet_id, "ranges": "A:D"}
)
ranges = result.get("valueRanges", [])
rows = ranges[0].get("values", []) if ranges else []
for row in rows:
print(row) # ['2026-04-12', 'Acme', '2.5', 'Review round 2']Wait — a row in my Sheet is just a Python list? Like ["2026-04-12", "Acme", "2.5", "Review round 2"]?
That is all it ever was. A list of strings. Now Python knows that too.
So I can filter rows by client name, sum the hours column, and build the time summary without opening the spreadsheet.
Filter, sum, format. The monthly time log becomes a function argument:
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}
)
ranges = result.get("valueRanges", [])
rows = ranges[0].get("values", []) if ranges else []
print(f"Read {len(rows)} rows from range {range_a1}")
return rowsMy time log is now a Python list. My accountant is going to be impressed.
All values come back as strings — even numbers. row[2] for hours is "2.5", not 2.5. Convert with float(row[2]) when you need to compute totals. The header row is always row rows[0] — skip it with rows[1:].
GOOGLESHEETS_BATCH_GET returns rows as a list of lists — each inner list is one row, each element is a cell value:
result = toolset.execute_action(
action=Action.GOOGLESHEETS_BATCH_GET,
params={'spreadsheetId': sheet_id, 'ranges': [range_a1]}
)
rows = result.get('valueRanges', [{}])[0].get('values', [])'A:D' means all rows in columns A through D. 'A1:D10' means the first 10 rows of those columns. The first row is usually the header.
Rows are lists of strings. Even numeric cells come back as strings — convert with float(row[2]) or int(row[2]) before doing arithmetic. Check len(row) before indexing to handle rows with fewer columns than expected.
Create a free account to get started. Paid plans unlock all tracks.