Skip to content

gsuite-calendar

Simple, Pythonic Google Calendar API client.

Installation

pip install gsuite-sdk   # gsuite_calendar ships inside the SDK

Quick Start

from gsuite_core import GoogleAuth
from gsuite_calendar import Calendar

# Authenticate
auth = GoogleAuth()
auth.authenticate()  # Opens browser for consent

calendar = Calendar(auth)

Reading Events

# Get today's events
for event in calendar.get_today():
    print(f"{event.start.strftime('%H:%M')} - {event.summary}")

# Get upcoming events (next 7 days)
for event in calendar.get_upcoming(days=7):
    print(f"{event.start}: {event.summary}")
    if event.location:
        print(f"  📍 {event.location}")
    if event.description:
        print(f"  📝 {event.description[:100]}...")

# Get events in a specific range
from datetime import datetime

events = calendar.get_events(
    time_min=datetime(2026, 2, 1),
    time_max=datetime(2026, 2, 28),
)

Event Properties

event = calendar.get_upcoming(days=1)[0]

# Basic info
event.id          # Event ID
event.summary     # Title
event.description # Description
event.location    # Location

# Times
event.start       # datetime
event.end         # datetime
event.is_all_day  # bool
event.timezone    # str, e.g. "America/Argentina/Buenos_Aires"

# Recurrence
event.is_recurring    # bool
event.recurrence      # Recurrence rule

# Attendees
for attendee in event.attendees:
    print(f"{attendee.email} - {attendee.response_status}")
    # response_status: needsAction, declined, tentative, accepted

# Links
event.html_link      # Link to Google Calendar
event.meet_link      # Google Meet link (if any)

# Metadata
event.created            # datetime
event.updated            # datetime
event.creator            # email of who created it
event.organizer          # email of who's organizing
event.recurring_event_id # parent event, for an occurrence of a recurring one

Creating Events

from datetime import datetime, timedelta

# Simple event
calendar.create_event(
    summary="Team Meeting",
    start=datetime(2026, 2, 15, 10, 0),
    end=datetime(2026, 2, 15, 11, 0),
)

# With all options
calendar.create_event(
    summary="Project Review",
    description="Quarterly review of project progress",
    location="Conference Room A",
    start=datetime(2026, 2, 15, 14, 0),
    end=datetime(2026, 2, 15, 15, 30),
    attendees=["alice@company.com", "bob@company.com"],
    send_updates="all",  # email the invitations ("all", "externalOnly", "none")
    meet=True,           # attach a Google Meet link -> event.meet_link
)

# All-day event
calendar.create_event(
    summary="Company Holiday",
    start=datetime(2026, 2, 20),
    all_day=True,
)

# Quick add (natural language)
calendar.quick_add("Lunch with John tomorrow at 12pm")

Updating Events

# Get an event
events = calendar.get_upcoming(days=7)
event = events[0]

# Update it (only the fields you pass change)
calendar.update_event(
    event_id=event.id,
    summary="Updated Meeting Title",
    location="New Location",
)

# Move it; end defaults to one hour after start
calendar.update_event(event.id, start=datetime(2026, 2, 16, 10, 0), send_updates="all")

Deleting Events

# Delete by event ID
calendar.delete_event(event_id="abc123xyz")

# Delete an event object
event = calendar.get_upcoming(days=1)[0]
calendar.delete_event(event_id=event.id)

Working with Multiple Calendars

# List all calendars
for cal in calendar.get_calendars():
    print(f"{cal.summary} ({cal.id})")
    print(f"  Primary: {cal.primary}")
    print(f"  Access: {cal.access_role}")

# Use a specific calendar
work_calendar = Calendar(auth, calendar_id="work@company.com")
events = work_calendar.get_upcoming(days=7)

# Or specify per-call
events = calendar.get_events(
    calendar_id="family@group.calendar.google.com",
    time_min=datetime(2026, 2, 1),
)

Free/Busy Queries

# Check availability across calendars
busy_times = calendar.get_free_busy(
    time_min=datetime(2026, 2, 15, 9, 0),
    time_max=datetime(2026, 2, 15, 18, 0),
    calendars=["me", "colleague@company.com"],
)

for cal_id, times in busy_times.items():
    print(f"{cal_id}:")
    for busy in times:
        print(f"  Busy: {busy['start']} - {busy['end']}")

Recurring Events

# Create recurring event
calendar.create_event(
    summary="Weekly Standup",
    start=datetime(2026, 2, 3, 9, 0),  # Monday
    end=datetime(2026, 2, 3, 9, 30),
    recurrence=["RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR"],
)

# Get recurring events (single_events=True expands them)
events = calendar.get_events(
    time_min=datetime(2026, 2, 1),
    time_max=datetime(2026, 2, 28),
    single_events=True,  # Returns each occurrence
)

# Occurrences of one recurring event
for occurrence in calendar.get_instances(event.id, time_max=datetime(2026, 3, 31)):
    print(occurrence.start)

# Get recurring events as single items
events = calendar.get_events(
    time_min=datetime(2026, 2, 1),
    time_max=datetime(2026, 2, 28),
    single_events=False,  # Returns master event only
)

Error Handling

from gsuite_core.exceptions import (
    GSuiteError,
    NotFoundError,
    RateLimitError,
)

try:
    calendar.delete_event("nonexistent_id")
except NotFoundError:
    print("Event not found")
except RateLimitError:
    print("Rate limited, retry later")
except GSuiteError as e:
    print(f"Calendar error: {e}")

Configuration

Uses gsuite-core settings. See gsuite-core README for auth configuration.

License

MIT