Capstone day. One function, two APIs, one dict handed to the caller. What numbers belong in your morning report?
Count of unread emails, count of calendar events for today — the two signals that tell you how packed your day looks?
Exactly. Two execute_action calls, each wrapped by the defensive .get pattern you've used all month. Build a dict with the two counts, hand it to whoever runs the function:
emails = toolset.execute_action(Action.GMAIL_FETCH_EMAILS, {"max_results": 10})
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": ""})
email_count = len(emails.get("messages", []))
event_count = len(events.get("items", []))So the report is just two counts in a dict — no writes, no side effects, just a snapshot of where my day stands?
The simplest useful morning report. Print it, log it to a sheet later, ship it via email — once the dict exists every downstream step is ordinary Python:
def morning_report() -> dict:
emails = toolset.execute_action(Action.GMAIL_FETCH_EMAILS, {"max_results": 10})
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": ""})
return {
"email_count": len(emails.get("messages", [])),
"event_count": len(events.get("items", [])),
}What if one API fails — should the function still return a partial dict, or bubble the error up?
Production code would wrap each call in try/except, default the failing count to None or -1, and keep the other API working. Capstone scope for this track returns the happy-path dict. Once you are on the next track, defensive wrappers are the first upgrade.
So I wrote a multi-API function in seven lines — that is the same skeleton I have repeated every week, just wired together?
That is the whole track in one function. Six API calls across four apps, each of them a drop-in replacement for another. You have built the muscle memory for every automation from here.
TL;DR: A morning report is just two reads and a return — the defensive patterns from every prior lesson carry the whole function.
execute_action + .get("messages", [])execute_action + .get("items", []){"email_count": ..., "event_count": ...}| Upgrade | Shape |
|---|---|
| try/except wrappers | each API defaulted independently |
| Sheets log | append the dict as a row for history |
Capstone day. One function, two APIs, one dict handed to the caller. What numbers belong in your morning report?
Count of unread emails, count of calendar events for today — the two signals that tell you how packed your day looks?
Exactly. Two execute_action calls, each wrapped by the defensive .get pattern you've used all month. Build a dict with the two counts, hand it to whoever runs the function:
emails = toolset.execute_action(Action.GMAIL_FETCH_EMAILS, {"max_results": 10})
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": ""})
email_count = len(emails.get("messages", []))
event_count = len(events.get("items", []))So the report is just two counts in a dict — no writes, no side effects, just a snapshot of where my day stands?
The simplest useful morning report. Print it, log it to a sheet later, ship it via email — once the dict exists every downstream step is ordinary Python:
def morning_report() -> dict:
emails = toolset.execute_action(Action.GMAIL_FETCH_EMAILS, {"max_results": 10})
events = toolset.execute_action(Action.GOOGLECALENDAR_FIND_EVENT, {"query": ""})
return {
"email_count": len(emails.get("messages", [])),
"event_count": len(events.get("items", [])),
}What if one API fails — should the function still return a partial dict, or bubble the error up?
Production code would wrap each call in try/except, default the failing count to None or -1, and keep the other API working. Capstone scope for this track returns the happy-path dict. Once you are on the next track, defensive wrappers are the first upgrade.
So I wrote a multi-API function in seven lines — that is the same skeleton I have repeated every week, just wired together?
That is the whole track in one function. Six API calls across four apps, each of them a drop-in replacement for another. You have built the muscle memory for every automation from here.
TL;DR: A morning report is just two reads and a return — the defensive patterns from every prior lesson carry the whole function.
execute_action + .get("messages", [])execute_action + .get("items", []){"email_count": ..., "event_count": ...}| Upgrade | Shape |
|---|---|
| try/except wrappers | each API defaulted independently |
| Sheets log | append the dict as a row for history |
Create a free account to get started. Paid plans unlock all tracks.