gcsa: a Pythonic object wrapper over the Google Calendar API
Pythonic wrapper for the Google Calendar API
At a glance
- What is it?
- Google Calendar Simple API turns the Calendar JSON into Python objects, so listing, creating and recurring events read like ordinary Python rather than request payloads. The convenience is real, and so is the cost of a wrapper sitting on top of a Google API that changes underneath it.
- Who is it for?
- gcsa suits a Python script or service that needs to read and write calendars without hand-building request bodies, especially one that benefits from the recurrence helpers and the iterable calendar object.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 101 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An object model instead of request payloads
The README describes `Google Calendar Simple API`, shortened to `gcsa`, as a library that simplifies event and calendar management in Google Calendars, and more specifically as a Pythonic object oriented adapter for the official API. That framing sets expectations correctly. It is not a replacement for the official client, and it is not a REST wrapper in the thin sense of passing dictionaries through. It models the calendar as objects you construct, attach and read.
The difference shows up in the smallest example, which iterates a calendar directly:
from gcsa.google_calendar import GoogleCalendar
calendar = GoogleCalendar('[email protected]')
for event in calendar:
print(event)There is no pagination handling, no body dictionary and no method call naming a Google endpoint. A calendar instance is iterable, so listing events is a for loop.
The repository topics hint at a wider surface than the README demonstrates. Alongside calendar, event and recurrence, the topics include attendee, conference, hangouts, freebusy and access-control-list, which suggests object classes for those areas exist in the package. The README itself does not document them, so treat that list as a pointer to the documentation rather than as a feature list.
Events are built with keyword arguments, not keyword arguments plus payload
Creating an event follows the same pattern. The `Event` class takes the title positionally and the rest as named arguments, including a start datetime, a location and a reminder offset:
from gcsa.event import Event
event = Event(
'The Glass Menagerie',
start=datetime(2020, 7, 10, 19, 0),
location='Záhřebská 468/21',
minutes_before_popup_reminder=15
)
calendar.add_event(event)Two things are worth noticing. The reminder is expressed the way a person thinks about it, as minutes before the popup, rather than as the reminder payload structure the underlying API expects. And `add_event` is a method on the calendar object, so the event is created against a specific calendar rather than a generic client.
The example also reveals an implicit dependency: `datetime` is used without an import line in the snippet, and the README suggests using `beautiful_date` to create `date` and `datetime` objects in your projects, linking to the author's own `beautiful-date` project. The library accepts standard library date objects, and the suggestion is about convenience, not a hard requirement.
Recurrence is a rule object, not a string you assemble
Repeating events go through the `gcsa.recurrence` module, where `Recurrence.rule` builds a rule from keyword arguments and the module supplies the frequency constants:
from gcsa.recurrence import Recurrence, DAILY
event = Event(
'Breakfast',
start=date(2020, 7, 16),
recurrence=Recurrence.rule(freq=DAILY)
)
calendar.add_event(event)This is where the wrapper earns its keep. The Google Calendar API expresses recurrence as an RFC-style rule string with keys such as frequency, interval, count and until, and a client that works at the JSON level makes you assemble that string by hand. Here the frequency is a named constant, `DAILY`, and the rule object is passed straight into the event constructor.
The cost of that abstraction is that the mapping between the rule object and the wire format is the library's business rather than yours. That is convenient for the common cases and one more thing to check against the documentation when your recurrence needs something less common, such as an end date or a set of excluded days.
Installing is one command, and the auth story is in the docs
The package is published on PyPI as `gcsa`, and the README gives two installation routes, one with uv:
uv add gcsaand one with pip:
pip install gcsaBoth are the ordinary one-liners you would expect from a library on PyPI, and the README points to a getting started page for more installation options, which is where the full documentation lives on Read the Docs.
That pointer is also where the gap sits. The example constructs `GoogleCalendar('[email protected]')` with nothing but an account address, and the README never shows how credentials reach the object. Google Calendar requires OAuth, and the credentials file, the scope list and the flow all have to be configured somewhere, but the README does not show it and the repository root contains no sample credentials file. Anyone starting with this library will need the getting started page before the first call works.
For local development, the repository layout has what you would expect: a `gcsa` package directory, a `tests` directory, a `tox.ini` for test environments, a `docs` directory with a Sphinx configuration and a `.readthedocs.yml` for building the documentation on Read the Docs.
Releases still run through a setup.py upload command
The version in the repository is declared in `setup.py`, which reads:
VERSION = '2.7.0'The rest of that file describes how a release is made, and the method is old-fashioned enough to be worth naming. A custom `UploadCommand` removes the previous `dist` directory, runs `setup.py sdist bdist_wheel --universal` to build a source distribution and a universal wheel, then runs `twine upload dist/*` against PyPI, and finally creates and pushes a git tag of the form `v{VERSION}`. A separate `BuildDoc` command runs `sphinx-build` over `docs/source` into `docs/html`, passing the version through as a define so the built documentation can display it.
The template for `setup.py` is credited in the README to `kennethreitz/setup.py`. What this tells you is that the packaging story is deliberately simple and explicit, which is nice to read, and that publishing still goes through a local command rather than a release workflow. The repository has no GitHub releases, so a user installing from source has no tagged history to navigate.
A wrapper inherits the pace of the API it wraps
The practical risk with a convenience layer over a hosted API is that the upstream surface changes and the layer is what stands between you and it. The README itself does not discuss this, and it does not document which parts of the Calendar API the library currently covers.
The repository state gives a partial answer. The last push was on 2026-07-14 and the repository is not archived, so work is happening on it, and the version in `setup.py` is 2.7.0. What is missing is any published release trail, since the repository has no GitHub releases, and any statement in the documentation about which Google API version it targets. Google names its own API versions in the request path, and a library that does not state which one it speaks to leaves you to infer it from behaviour.
The design decision that helps here is that the object model is small. Events, calendars and recurrence rules are stable concepts, and the parts most likely to drift, such as conference data or freebusy queries, are the parts the README does not promise.
The official client is the alternative, and the difference is in the payload
The comparison worth making is with the official Google API client that the README points to. Both talk to the same endpoint with the same OAuth scope, and both will list, create and delete events. The difference is the layer you work at.
With the official client you construct the request body as the API defines it, a dictionary whose keys are the Google field names, with times as RFC 3339 strings and recurrence as a rule string. The client is faithful and complete, and every Google field is reachable, including the ones gcsa does not model. It is also verbose, and the knowledge of the wire format sits in your code.
With gcsa the vocabulary is Python. You pass a `datetime`, a `date` and `Recurrence.rule(freq=DAILY)`, and the library handles the conversion. You give up direct access to any field the wrapper has not modelled, and you add a dependency whose version you now track.
The second approach is a better fit for scripts, scheduled jobs and internal tools where the calendar operations are simple and the JSON details are noise. The first is the better fit when you need a Google field gcsa does not expose, and the README gives you no way to check that list without reading the documentation.
Editorial conclusion
gcsa suits a Python script or service that needs to read and write calendars without hand-building request bodies, especially one that benefits from the recurrence helpers and the iterable calendar object. It does not suit a team that wants an official client with a support commitment, and it is the wrong choice for calendar features the wrapper does not model, such as the conference, attendee list, access control and freebusy areas its repository topics mention but the README does not cover. Verify first how you pass credentials to GoogleCalendar, since the README example shows only the account address, and pin the version, because the repository has no GitHub releases and the setup.py still carries the release ritual.
Frequently asked questions
How do I install the Google Calendar Simple API package?
The README gives two options: uv add gcsa, or pip install gcsa. The package is published on PyPI as gcsa, and the getting started page on the Read the Docs documentation has further installation options.
How do I list Google Calendar events with gcsa?
A GoogleCalendar object is iterable, so you construct it with the account address and loop over it directly, for example for event in calendar: print(event). No pagination or request body handling appears in the example.
How do I create a recurring event with gcsa?
Use the Recurrence class from gcsa.recurrence and a frequency constant such as DAILY, then pass it to the event: recurrence=Recurrence.rule(freq=DAILY). The event is added with calendar.add_event(event).
Does gcsa support conference, attendee and freebusy features?
Those areas appear among the repository topics, alongside calendar, event and recurrence, but the README only documents event creation, listing and recurrence. The full documentation on Read the Docs is the place to check the current class coverage.
What licence is the Google Calendar Simple API released under?
The repository is licensed under MIT, with the LICENSE file at the root, and the project is written in Python with the package code under the gcsa directory.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kuzmoyev-google-calendar-simple-api)Was this useful?