Simple API for Google Calendar management
—
Calendar sharing, access control rules, and permission management for collaborative calendar usage. The AccessControlRule class manages who can access calendars and what level of access they have.
from gcsa.acl import AccessControlRule, ACLRole, ACLScopeTypeRepresents Access Control List (ACL) rules for calendar permissions, controlling who can access a calendar and what they can do with it.
class AccessControlRule:
def __init__(
self,
role: str,
scope_type: str,
acl_id: str = None,
scope_value: str = None
):
"""
Create an access control rule for a calendar.
Parameters:
- role (str): Access level ('none', 'freeBusyReader', 'reader', 'writer', 'owner')
- scope_type (str): Type of scope ('default', 'user', 'group', 'domain')
- acl_id (str): Unique identifier for the ACL rule
- scope_value (str): Email address or domain for user/group/domain scopes
"""
@property
def id(self) -> str:
"""
Get the ACL rule ID.
Returns:
str: Unique identifier for the ACL rule
"""Methods for managing access control rules through the main GoogleCalendar client.
def get_acl_rules(
self,
calendar_id: str = None,
max_results: int = None,
page_token: str = None,
show_deleted: bool = None,
sync_token: str = None
):
"""
Get access control rules for a calendar.
Parameters:
- calendar_id (str): Calendar identifier
- max_results (int): Maximum number of rules to return
- page_token (str): Token for pagination
- show_deleted (bool): Whether to include deleted rules
- sync_token (str): Token for incremental sync
Returns:
List of AccessControlRule objects
"""
def get_acl_rule(self, acl_id: str, calendar_id: str = None):
"""
Get a specific access control rule.
Parameters:
- acl_id (str): ACL rule identifier
- calendar_id (str): Calendar identifier
Returns:
AccessControlRule object
"""
def add_acl_rule(
self,
acl_rule,
calendar_id: str = None,
send_notifications: bool = None
):
"""
Add an access control rule to a calendar.
Parameters:
- acl_rule (AccessControlRule): ACL rule to add
- calendar_id (str): Calendar identifier
- send_notifications (bool): Whether to send notification emails
Returns:
Created AccessControlRule object with assigned ID
"""
def update_acl_rule(
self,
acl_rule,
acl_id: str = None,
calendar_id: str = None,
send_notifications: bool = None
):
"""
Update an existing access control rule.
Parameters:
- acl_rule (AccessControlRule): Modified ACL rule
- acl_id (str): ACL rule identifier
- calendar_id (str): Calendar identifier
- send_notifications (bool): Whether to send notification emails
Returns:
Updated AccessControlRule object
"""
def delete_acl_rule(self, acl_id: str, calendar_id: str = None):
"""
Delete an access control rule.
Parameters:
- acl_id (str): ACL rule identifier
- calendar_id (str): Calendar identifier
"""class ACLRole:
NONE = "none" # No access
FREE_BUSY_READER = "freeBusyReader" # Can see free/busy information only
READER = "reader" # Can read event details
WRITER = "writer" # Can create and modify events
OWNER = "owner" # Full control over calendarclass ACLScopeType:
DEFAULT = "default" # Default access for all users
USER = "user" # Specific user by email
GROUP = "group" # Google group by email
DOMAIN = "domain" # Entire domainfrom gcsa.google_calendar import GoogleCalendar
from gcsa.acl import AccessControlRule, ACLRole, ACLScopeType
gc = GoogleCalendar()
# Share calendar with specific user (read access)
read_rule = AccessControlRule(
role=ACLRole.READER,
scope_type=ACLScopeType.USER,
scope_value="user@example.com"
)
gc.add_acl_rule(read_rule, calendar_id="my_calendar_id")
# Give write access to another user
write_rule = AccessControlRule(
role=ACLRole.WRITER,
scope_type=ACLScopeType.USER,
scope_value="colleague@example.com"
)
gc.add_acl_rule(write_rule, calendar_id="my_calendar_id")# Share calendar with entire domain (free/busy only)
domain_rule = AccessControlRule(
role=ACLRole.FREE_BUSY_READER,
scope_type=ACLScopeType.DOMAIN,
scope_value="company.com"
)
gc.add_acl_rule(domain_rule, calendar_id="shared_calendar_id")
# Make calendar public (read-only)
public_rule = AccessControlRule(
role=ACLRole.READER,
scope_type=ACLScopeType.DEFAULT
)
gc.add_acl_rule(public_rule, calendar_id="public_calendar_id")# Share with Google group
group_rule = AccessControlRule(
role=ACLRole.WRITER,
scope_type=ACLScopeType.GROUP,
scope_value="team@company.com"
)
gc.add_acl_rule(group_rule, calendar_id="team_calendar_id")# List all ACL rules for a calendar
acl_rules = gc.get_acl_rules(calendar_id="my_calendar_id")
for rule in acl_rules:
print(f"Rule {rule.id}: {rule.role} for {rule.scope_type} {rule.scope_value}")
# Update an existing rule
existing_rule = gc.get_acl_rule("rule_id", calendar_id="my_calendar_id")
existing_rule.role = ACLRole.WRITER # Upgrade from reader to writer
gc.update_acl_rule(existing_rule, calendar_id="my_calendar_id")
# Remove access
gc.delete_acl_rule("rule_id", calendar_id="my_calendar_id")# Add rule with notifications
new_rule = AccessControlRule(
role=ACLRole.READER,
scope_type=ACLScopeType.USER,
scope_value="newuser@example.com"
)
gc.add_acl_rule(
new_rule,
calendar_id="shared_calendar",
send_notifications=True # Send email notification to user
)
# Update rule without notifications
existing_rule.role = ACLRole.WRITER
gc.update_acl_rule(
existing_rule,
calendar_id="shared_calendar",
send_notifications=False # Silent update
)# Transfer ownership to another user
owner_rule = AccessControlRule(
role=ACLRole.OWNER,
scope_type=ACLScopeType.USER,
scope_value="newowner@example.com"
)
gc.add_acl_rule(owner_rule, calendar_id="calendar_to_transfer")
# Note: Original owner automatically becomes a writer after transfer# Create a calendar with specific sharing settings
from gcsa.calendar import Calendar
# Create new calendar
new_calendar = Calendar(
summary="Project Calendar",
description="Shared project calendar"
)
created_calendar = gc.add_calendar(new_calendar)
# Set up multiple access levels
acl_rules = [
# Project manager gets full access
AccessControlRule(
role=ACLRole.OWNER,
scope_type=ACLScopeType.USER,
scope_value="manager@company.com"
),
# Team members can edit
AccessControlRule(
role=ACLRole.WRITER,
scope_type=ACLScopeType.GROUP,
scope_value="project-team@company.com"
),
# Stakeholders can view
AccessControlRule(
role=ACLRole.READER,
scope_type=ACLScopeType.GROUP,
scope_value="stakeholders@company.com"
),
# Company can see free/busy
AccessControlRule(
role=ACLRole.FREE_BUSY_READER,
scope_type=ACLScopeType.DOMAIN,
scope_value="company.com"
)
]
# Apply all rules
for rule in acl_rules:
gc.add_acl_rule(rule, calendar_id=created_calendar.id)from googleapiclient.errors import HttpError
try:
# Attempt to add ACL rule
rule = AccessControlRule(
role=ACLRole.WRITER,
scope_type=ACLScopeType.USER,
scope_value="invalid@email"
)
gc.add_acl_rule(rule, calendar_id="calendar_id")
except HttpError as e:
if e.resp.status == 400:
print("Invalid ACL rule parameters")
elif e.resp.status == 403:
print("Insufficient permissions to modify ACL")
elif e.resp.status == 404:
print("Calendar or ACL rule not found")
else:
print(f"API error: {e}")# Remove all non-owner rules from a calendar
acl_rules = gc.get_acl_rules(calendar_id="private_calendar")
for rule in acl_rules:
if rule.role != ACLRole.OWNER:
gc.delete_acl_rule(rule.id, calendar_id="private_calendar")
# Copy ACL from one calendar to another
source_rules = gc.get_acl_rules(calendar_id="source_calendar")
for rule in source_rules:
if rule.role != ACLRole.OWNER: # Don't copy ownership
new_rule = AccessControlRule(
role=rule.role,
scope_type=rule.scope_type,
scope_value=rule.scope_value
)
gc.add_acl_rule(new_rule, calendar_id="target_calendar")Access control in GCSA provides fine-grained permission management for calendar sharing, supporting individual users, groups, domains, and public access with different levels of permissions from free/busy visibility to full ownership.
Install with Tessl CLI
npx tessl i tessl/pypi-gcsa