A dict-of-lists preserves source but forces branching. A tagged matrix — a list where every row has the same keys — lets one loop process everything uniformly while keeping the source label. What shape should each row have?
{"source": "gmail", "content": "...", "id": "..."}? Three fields per row, same three for every source?
Exactly. Consistent schema across rows is the whole point — downstream code reads row["content"] or filters by row["source"] == "tasks" without worrying which API produced the row:
rows = [
{"source": "gmail", "content": m.get("snippet", ""), "id": m.get("id", "")}
for m in emails.get("messages", [])
]So we do the same shape three times — once per source — and concatenate the lists.
Yes. The source tag makes the merged list still filterable. Here's the full function:
def build_source_matrix(max_items: int) -> list:
emails = toolset.execute_action(Action.GMAIL_FETCH_EMAILS, {"max_results": max_items})
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": ""})
tasks = toolset.execute_action(Action.GOOGLETASKS_LIST_TASKS, {"max_results": max_items})
gmail_rows = [{"source": "gmail", "content": m.get("snippet", ""), "id": m.get("id", "")} for m in emails.get("messages", [])]
cal_rows = [{"source": "calendar", "content": e.get("summary", ""), "id": e.get("id", "")} for e in events.get("items", [])]
task_rows = [{"source": "tasks", "content": t.get("title", ""), "id": t.get("id", "")} for t in tasks.get("items", [])]
matrix = gmail_rows + cal_rows + task_rows
print(f"Built matrix of {len(matrix)} rows across 3 sources")
return matrixIf I want to add a timestamp field later, do I break existing callers?
No. Existing callers read specific keys like row["content"]. Adding a new key is a strict superset — nothing that worked before breaks. The matrix is extensible by design.
So I can now feed this one list into any downstream transform — search, sort, filter — and it works the same regardless of which API fed each row?
That is the power of uniform shape. One list, three sources, any transform. This is the data structure most production automations hand to the next stage of the pipeline.
TL;DR: A list of dicts where every row has the same schema — {source, content, id} — unifies heterogeneous API outputs.
| Shape | Loses origin? |
|---|---|
| flat list of strings | yes |
| list of tagged dicts | no — row["source"] retains it |
A dict-of-lists preserves source but forces branching. A tagged matrix — a list where every row has the same keys — lets one loop process everything uniformly while keeping the source label. What shape should each row have?
{"source": "gmail", "content": "...", "id": "..."}? Three fields per row, same three for every source?
Exactly. Consistent schema across rows is the whole point — downstream code reads row["content"] or filters by row["source"] == "tasks" without worrying which API produced the row:
rows = [
{"source": "gmail", "content": m.get("snippet", ""), "id": m.get("id", "")}
for m in emails.get("messages", [])
]So we do the same shape three times — once per source — and concatenate the lists.
Yes. The source tag makes the merged list still filterable. Here's the full function:
def build_source_matrix(max_items: int) -> list:
emails = toolset.execute_action(Action.GMAIL_FETCH_EMAILS, {"max_results": max_items})
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": ""})
tasks = toolset.execute_action(Action.GOOGLETASKS_LIST_TASKS, {"max_results": max_items})
gmail_rows = [{"source": "gmail", "content": m.get("snippet", ""), "id": m.get("id", "")} for m in emails.get("messages", [])]
cal_rows = [{"source": "calendar", "content": e.get("summary", ""), "id": e.get("id", "")} for e in events.get("items", [])]
task_rows = [{"source": "tasks", "content": t.get("title", ""), "id": t.get("id", "")} for t in tasks.get("items", [])]
matrix = gmail_rows + cal_rows + task_rows
print(f"Built matrix of {len(matrix)} rows across 3 sources")
return matrixIf I want to add a timestamp field later, do I break existing callers?
No. Existing callers read specific keys like row["content"]. Adding a new key is a strict superset — nothing that worked before breaks. The matrix is extensible by design.
So I can now feed this one list into any downstream transform — search, sort, filter — and it works the same regardless of which API fed each row?
That is the power of uniform shape. One list, three sources, any transform. This is the data structure most production automations hand to the next stage of the pipeline.
TL;DR: A list of dicts where every row has the same schema — {source, content, id} — unifies heterogeneous API outputs.
| Shape | Loses origin? |
|---|---|
| flat list of strings | yes |
| list of tagged dicts | no — row["source"] retains it |
Create a free account to get started. Paid plans unlock all tracks.