Before you create a submission deadline event, you need to know which calendar to put it in. You have a personal calendar, a lab calendar, and a department calendar. How do you get the list?
count_emails from Day 3 followed the same pattern — call an action, get a list back from the response. For calendars I'd call GOOGLECALENDAR_LIST_CALENDARS and parse the response.
Exact same pattern. The action name changes; the call shape is identical. {} as params because list operations don't need filters — you want all calendars:
result = toolset.execute_action(Action.GOOGLECALENDAR_LIST_CALENDARS, {})
calendars = result.get("items", [])Why .get("items", []) and not .get("calendars", []) like Gmail uses messages? Is the key different for Calendar?
Yes — Calendar API uses items as the list key, not messages. This is why you check the response shape for each new action before parsing: the outer wrapper changes between APIs. Same .get(key, default) reflex, different key name. The response shape is documented in the Composio action catalog — and you can always print(result.keys()) on a real response to check.
So I parse the items list, find my lab calendar by its summary field, and that's the calendar ID I pass to create_event on Day 12.
The list is the discovery step. The ID is the permanent reference. Here's the complete function:
def list_calendars() -> list:
result = toolset.execute_action(Action.GOOGLECALENDAR_LIST_CALENDARS, {})
calendars = result.get("items", [])
print(f"Found {len(calendars)} calendars")
return calendarsI can see my personal calendar, lab calendar, and department calendar from a Python function. The deadline management system I've been putting off just became a one-afternoon project.
One note: GOOGLECALENDAR_LIST_CALENDARS returns all calendars you have access to — including shared and read-only ones. Check the accessRole field to confirm you have writer or owner access before trying to create events in a calendar. Creating events in a read-only calendar returns an error.
Same call shape as Gmail, different action and response key:
result = toolset.execute_action(Action.GOOGLECALENDAR_LIST_CALENDARS, {})
calendars = result.get("items", []) # 'items', not 'messages'| Field | Meaning |
|---|---|
id | Unique calendar ID — use this for event creation |
summary | Display name (e.g. "Lab Calendar") |
accessRole | "owner", "writer", "reader" — determines what you can do |
lab_cal = next((c for c in calendars if "lab" in c["summary"].lower()), None)Before you create a submission deadline event, you need to know which calendar to put it in. You have a personal calendar, a lab calendar, and a department calendar. How do you get the list?
count_emails from Day 3 followed the same pattern — call an action, get a list back from the response. For calendars I'd call GOOGLECALENDAR_LIST_CALENDARS and parse the response.
Exact same pattern. The action name changes; the call shape is identical. {} as params because list operations don't need filters — you want all calendars:
result = toolset.execute_action(Action.GOOGLECALENDAR_LIST_CALENDARS, {})
calendars = result.get("items", [])Why .get("items", []) and not .get("calendars", []) like Gmail uses messages? Is the key different for Calendar?
Yes — Calendar API uses items as the list key, not messages. This is why you check the response shape for each new action before parsing: the outer wrapper changes between APIs. Same .get(key, default) reflex, different key name. The response shape is documented in the Composio action catalog — and you can always print(result.keys()) on a real response to check.
So I parse the items list, find my lab calendar by its summary field, and that's the calendar ID I pass to create_event on Day 12.
The list is the discovery step. The ID is the permanent reference. Here's the complete function:
def list_calendars() -> list:
result = toolset.execute_action(Action.GOOGLECALENDAR_LIST_CALENDARS, {})
calendars = result.get("items", [])
print(f"Found {len(calendars)} calendars")
return calendarsI can see my personal calendar, lab calendar, and department calendar from a Python function. The deadline management system I've been putting off just became a one-afternoon project.
One note: GOOGLECALENDAR_LIST_CALENDARS returns all calendars you have access to — including shared and read-only ones. Check the accessRole field to confirm you have writer or owner access before trying to create events in a calendar. Creating events in a read-only calendar returns an error.
Same call shape as Gmail, different action and response key:
result = toolset.execute_action(Action.GOOGLECALENDAR_LIST_CALENDARS, {})
calendars = result.get("items", []) # 'items', not 'messages'| Field | Meaning |
|---|---|
id | Unique calendar ID — use this for event creation |
summary | Display name (e.g. "Lab Calendar") |
accessRole | "owner", "writer", "reader" — determines what you can do |
lab_cal = next((c for c in calendars if "lab" in c["summary"].lower()), None)Create a free account to get started. Paid plans unlock all tracks.