Working with the Google Calendar API in Python3.6

butteredwaffles
5 min readSep 7, 2018

--

An API is a way to get data from an online source.

There’s APIs for anything — bibliography, libraries, books, resources, and much more. There’s even one for Star Wars. When you want information from a resource, most of the time you send something called a request. The information (or rejection!) that the server sends back is called a response. You’ll get more familiar with this terminology as time gets on. For this usage, you don’t have to get too in-depth, but make sure you know at least what these are.

So how do I use them?

Well, every API is different. To get what you want, you have to read the API’s documentation, which are instructions, and follow it exactly. Otherwise, you’ll find that it’s not going to work. A lot of more public API’s don’t require you to do any kind of authentication — that is, verifying that you are who you say you are and you’re doing what you said you would be doing with their service. Take for example the Star Wars API. You can make a request to that without providing any extra information about yourself and just get information you want!

However, think about it. If Google allowed anyone to access your data without any indication of who they are, that would be a huge privacy concern. This is why you have to provide credentials to show that you have access to the account you’re manipulating. API keys are a common form of this. It’s just a token that gives you access — if you don’t have it or it’s incorrect, it’ll spit back a 403 error (forbidden).

What type of tools do I use to get a response back?

Most API’s use the JSON format to send data. Python has a way to deal with this using the built-in json module. However, the Google Calendar API comes in a module, and handles the conversions itself.

Once you get the data, it’s typically turned into a dictionary. So in order to use API's, make sure you understand dictionaries well. If you need to catch up, read this URL. The rest of this guide will assume you understand them.

Google uses these things called scopes to figure out what you’re allowed to do on the account. We’re going to be referring to two articles in their documentation for this project — the Create Calender Event option and the basic Quickstart.

Note that you should not blindly copy-paste from this guide — there are a couple things that depend on the user and system.

Quickstart

Follow the directions in the Quickstart article up to step 3. We’re going to be doing something a little different, so the code in the example won’t work for us. See if you can understand what the example is doing, though! If you don’t get everything, that’s okay — there’s probably new things in there.

We will assume you have the credentials.json file in the same folder as your python script. If you don't, go back to the beginning of the quickstart :p

In addition, if you have a token.json file in your directory, delete it.

Creating Events

Now we’re going to get into the actual code! First, let’s set up our imports. (Note that all the code in this notebook builds off of each other, as in one section being right after another. As you read, try to figure out how you would write this into your own program.)

from googleapiclient.discovery import buildfrom httplib2 import Httpfrom oauth2client import file, client, toolsfrom datetime import datetime

To read and write to the account’s calendar, we’re going to have something called a scope. An API’s scope declares what you’re allowed to do and what you will be doing. The very first line tells Google that we are using all features of the calendar.

After that, we tell Google to store new credentials in a file called token.json. Remember, whenever you change the SCOPE, delete token.json!

.get() is a safe way to get data from a dictionary. If the dictionary doesn't have that key/value, it'll return None. That's why in the if statement it says if not creds - If store.get() didn't work, creds will be None, and our code then fetches data from our credentials.json and updates everything!

Now, we create a variable called service. This is what we'll be using the most to deal with this API.

SCOPES = "https://www.googleapis.com/auth/calendar"store = file.Storage('token.json')creds = store.get()if not creds or creds.invalid:    flow = client.flow_from_clientsecrets('credentials.json', SCOPES)    creds = tools.run_flow(flow, store)    service = build('calendar', 'v3', http=creds.authorize(Http()))

Now, let’s check if the user actually has access to change the calendar. Straight from Google’s docs….

"calendarId is the calendar identifier and can either be the email address of the calendar on which to create the event or a special keyword 'primary' which will use the primary calendar of the logged in user. If you don't know the email address of the calendar you would like to use, you can check it in the calendar's settings of the Google Calendar web UI (in the section "Calendar Address").

To be safe, this will use the keyword ‘primary’. If you’re inputting an email address, go ahead and use that as the calendar ID. However, the address has to match up with the account you made the credentials with.

calendar_list_entry = service.calendarList().get(calendarId='primary').execute()if calendar_list_entry['accessRole']:    # This next section's code will be here

Now, let’s create the event you want to be sent. Remember how I said earlier everything’s in dictionaries? We’re going to be using those now.

First, however, we have to get the information from the user. We’ll need to do something special to get the datetimes. To get those, we use the datetime module that we imported earlier. The code below uses datetime's strptime method to turn the user's input into a datetime object, which we then convert back to a format used by Google!

startTime = datetime.strptime(input("Please enter in the start time for the event in this format: (ex. September 02, 2018, 09:00PM) "), '%B %m, %Y, %I:%M%p').strftime('%Y-%m-%dT%H:%M:%S.%fZ')endTime = datetime.strptime(input("Please enter in the end time for the event in this format: (es. September 03, 2018, 11:25AM) "), '%B %m, %Y, %I:%M%p').strftime('%Y-%m-%dT%H:%M:%S.%fZ')

Remember — change your timezone to the one used by your user. I’m in New York’s timezone, so that’s what I put. Google uses a specific code for what timezone you’re in — to know which one to use, click here.

We’re almost done.

event = {    'summary': input("What's the name of the event? "),    # You can put inputs like this in dictionaries - it's stored in the key value directly, so there's no reason why not to. Continue to do this for all the information    # you need in the event, except for the times, which are already done    'location': snip,    'description': snip,    'start': {        'dateTime': startTime,        'timeZone': 'America/New_York',    },    'end': {        'dateTime': endTime,        'timeZone': 'America/New_York',    },}

Now, all that’s left to do is send off the data!

event = service.events().insert(calendarId='primary', body=event).execute()print(f"The event has been created! View it at {event.get('htmlLink')}!")

And that’s it!

You can do much more — such as add people that will be at the event (using their email), set the event to occur on a time schedule, or even edit how the person is reminded of it — however, this is the basics. Hopefully, after you’ve read this you can read the documentation and figure out how to use those features yourself!

--

--