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.
Metadata
Release files for entirius-py-google-calendar-sdk 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| entirius_py_google_calendar_sdk-2.0.0.tar.gz | 54.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| entirius_py_google_calendar_sdk-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 67.7 kB
Release files / entirius_py_google_calendar_sdk-2.0.0.tar.gz
| Download URL | entirius_py_google_calendar_sdk-2.0.0.tar.gz |
|---|---|
| Size | 54.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d3ab3bc05bcd92583764dbeb6e6a6dbbdab047b1a3ae6afdd25168ce9755d8d1
|
|
BLAKE2b-256 checksum How to use checksums |
b0a4dab8697cce332812103428af4c031f7d1d5a3bd1b0d8f282c267066a3f2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|
Release files / entirius_py_google_calendar_sdk-2.0.0-py3-none-any.whl
| Download URL | entirius_py_google_calendar_sdk-2.0.0-py3-none-any.whl |
|---|---|
| Size | 13.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d9dc891f16a94c8587839dae19e5cf4bdbbe51bb47cfd55ae3040c2d7c6d8164
|
|
BLAKE2b-256 checksum How to use checksums |
b3276239014eedd85799dab7bec0e59f535064527d01721b4df94c81b1de6e2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|