google-calendar-sdk
Pure-Python wrapper around Google Calendar API v3 for service-account flows with domain-wide delegation. Used by Volkanos modules that book slots on behalf of a real user (consultations, demos, deliveries) — most prominently the booking widget in django-contact-forms.
This SDK does one thing: talk to Google Calendar. It has no Django, no Volkanos coupling, no business logic about who can book what. Callers decide when to query, what to write, and which exceptions to surface.
Install
uv pip install entirius-py-google-calendar-sdk
Or as a dependency in pyproject.toml:
"entirius-py-google-calendar-sdk>=2.0.0"
Use
from datetime import datetime, timezone
from google_calendar_sdk import GoogleCalendarClient
client = GoogleCalendarClient(
credentials_path="/app/credentials/sa.json",
impersonate_email="bookings@yourdomain.com",
calendar_id="primary", # or a shared calendar ID
)
free = client.is_slot_free(
start=datetime(2026, 4, 20, 14, 0, tzinfo=timezone.utc),
end=datetime(2026, 4, 20, 14, 30, tzinfo=timezone.utc),
timezone="Europe/Warsaw",
)
if free:
event = client.create_event(
start=datetime(2026, 4, 20, 14, 0, tzinfo=timezone.utc),
end=datetime(2026, 4, 20, 14, 30, tzinfo=timezone.utc),
summary="Consultation - Jan",
attendee_email="jan@example.com",
description="Booking via website widget",
timezone="Europe/Warsaw",
create_meet_link=True,
)
print(event.event_id, event.meet_link)
Service-account setup
- Create a Google Cloud project, enable the Calendar API.
- Create a service account with domain-wide delegation.
- In Google Workspace admin: grant the service account the scope
https://www.googleapis.com/auth/calendar. - Download the JSON key. Mount it inside the container as a private file (e.g.
/app/credentials/sa.json). - The
impersonate_emailargument is the real user the service account acts as — events are created on that user'sprimarycalendar so they receive the invite and own the event.
Free-busy semantics
get_busy_periods always queries the impersonated user's primary calendar. If calendar_id is set to anything other than "primary", the shared calendar is queried as well — and busy periods from both are merged. This is the standard pattern for "the consultant has both a personal calendar AND a shared booking calendar; both must be free".
Tests
pytest
Tests fully mock googleapiclient.discovery.build so no network access is required.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file entirius_py_google_calendar_sdk-2.0.0.tar.gz.
File metadata
- Download URL: entirius_py_google_calendar_sdk-2.0.0.tar.gz
- Upload date:
- Size: 54.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3ab3bc05bcd92583764dbeb6e6a6dbbdab047b1a3ae6afdd25168ce9755d8d1
|
|
| MD5 |
3e0c5b88deca10aae9b255bad4a49346
|
|
| BLAKE2b-256 |
b0a4dab8697cce332812103428af4c031f7d1d5a3bd1b0d8f282c267066a3f2d
|
File details
Details for the file entirius_py_google_calendar_sdk-2.0.0-py3-none-any.whl.
File metadata
- Download URL: entirius_py_google_calendar_sdk-2.0.0-py3-none-any.whl
- Upload date:
- Size: 13.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9dc891f16a94c8587839dae19e5cf4bdbbe51bb47cfd55ae3040c2d7c6d8164
|
|
| MD5 |
efb3c119e289bd5d67e00c23345c7969
|
|
| BLAKE2b-256 |
b3276239014eedd85799dab7bec0e59f535064527d01721b4df94c81b1de6e2d
|