Question

I want to access the Google Calendar API to insert entries with Python. I created a Service account on the Google API console, added an private key, downloaded it.

But when I try to modify anyting of my calendar, it is on the same account, I get the following error message. Reading works.

Code is

import httplib2

from oauth2client.client import SignedJwtAssertionCredentials 
from apiclient.discovery import build

event = {
         'summary' : 'Appointment',
         'location' : 'Somewhere',
         'start' : {
                    'dateTime' : '2012-09-03T10:00:00.000-07:00'
                    },
         'end' :    {
                 'dateTime' : '2012-09-03T10:25:00.000-07:00'
                    }
}


f = file("key.p12", "rb")
key = f.read()
f.close()

credentials = SignedJwtAssertionCredentials(
                                                service_account_name='423291807109-XXXXXXXXXXXXXXXXxx@developer.gserviceaccount.com',
                                                private_key=key,

                                                scope='https://www.googleapis.com/auth/calendar'                                            
                                            )

http = httplib2.Http()
http = credentials.authorize(http)

service = build('calendar', 'v3', http=http)
request = service.events().insert(calendarId='XXXXXXXXXXXXXXXXXX@group.calendar.google.com', body=event)

response = request.execute()

print(response)

Error message is:

apiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/calendar/v3/calendars/XXXXXXXXXXXXXXXXXXX@group.calendar.google.com/events?alt=json returned "Forbidden">

I would have thought that I can access my own data with this service account, but it seems not to be.

Google claims that

After the Service Account has been created, you will also have access to the client ID associated with the private key. You will need both when coding your application. - https://developers.google.com/accounts/docs/OAuth2?hl=de#scenarios

I googled about 2 hours, but it seems to be documented very bad. Is there a way I can insert new events via the Google Calendar API without user interaction (aka 3-legged OAuth) or is there a way to fix it?

I just found deprecated ClientLoging. Why does Google makes it that difficult?

Kind regards

Was it helpful?

Solution

I realized that 3-stepped OAuth works if one dumps the resulting credentials to JSON and reads them in every time you need them.

So the flow is: Add your client_secrets.json as stated on Google API in the same folder as this script. Grab the key from the url given in the prompt. Enter it on request to the prompt. Party!11. I hope these credentials last forever.

from oauth2client.client import flow_from_clientsecrets

flow = flow_from_clientsecrets('client_secrets.json',
                               scope='https://www.googleapis.com/auth/calendar',
                               redirect_uri='urn:ietf:wg:oauth:2.0:oob')

auth_uri = flow.step1_get_authorize_url()
print('Visit this site!')
print(auth_uri)
code = raw_input('Insert the given code!')
credentials = flow.step2_exchange(code)
print(credentials)

with open('credentials', 'wr') as f:
    f.write(credentials.to_json())

Now, in the application itself:

def __create_service():
    with open('credentials', 'rw') as f:
        credentials = Credentials.new_from_json(f.read())

    http = httplib2.Http()
    http = credentials.authorize(http)

    return build('calendar', 'v3', http=http)

To get a service object, one can now call

service = __create_service()

and use the API on it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top