Skip to content
Advertisement

Refreshing Authentication token for Google Calendar API with Python on Raspberry Pi

We are prototyping on a Raspberry Pi using the Google Calendar API.

Each user of this service will connect his or her own calendar to the Raspberry Pi and use the calendar information.

The Raspberry Pi we are using does not have a keyboard or display connected to it.

We are planning to connect a smartphone to the Raspberry Pi and have it set up a calendar, but we are using SSH to temporarily complete the authentication process.

We were able to retrieve the calendar information by following the steps below. https://developers.google.com/calendar/quickstart/python

But after about two weeks, an authentication error occurred. It may depend on the expiration date of the refresh token. Authentication once every two weeks is very annoying to customers. Can we get around this?

We found out about Delegating domain-wide authority. https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority

Does this solve our problem? Can this be used to display the Calendar for domain-independent email addresses? For example, if we delegate to admin@example.com can we get the Calendar information associated with example@gmail.com?

We have already been struggling with this for months. Please give us any advice you can.

Add: Our code is as shown in the sample, but we will describe it here.

if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
        creds.refresh(Request())
    else:
        flow = InstalledAppFlow.from_client_secrets_file(
            '/home/pi/credentials.json', SCOPES)
// --- Try Kelo's advice ------------------------
        flow.params['access_type'] = 'offline'
        flow.params['include_granted_scopes'] = 'true'
// --- Try Kelo's advice ------------------------
        creds = flow.run_console()
        # Save the credentials for the next run
        with open('/home/pi/token.pickle', 'wb') as token:
            pickle.dump(creds, token)

If we use the wizard, we will see this warning. enter image description here

Advertisement

Answer

Google API and direct access

Whenever you access user data, the user will need to authorize that, there is no way to go around this fact. You will always require a UI with the ability to “log in” or pass in a token. At the moment you are doing it via SSH, which is fine.

One part of your question is addressed towards whether you can get permanent access to the Google APIs from a device that does not have a interactive UI, and the answer is unfortunately, no, you cannot. Assuming your display is only able to give information, and not able to log-in to Google, then you’ll need to do it via SSH or another method.

Service Accounts and non UI methods

Another question of yours is about whether Service accounts will work for your purposes. Unfortunately the answer is also no. Service accounts are for Workspace domains (people in the same organization) which I understand is not your case.

Offline Access

I understand that this is an IoT device and not a web server. However, there is a type of access called the “Offline” type. This is made available by Google to Web Server type applications.

enter image description here

Which is found when creating the credentials.

To be clear, I do not think this is a good solution for you. It would be possible, but not for people without a lot of tech knowledge, as each user would have to manage the Pi-as-server.

This is what a lot of people do with their IoT devices. Then they can “visit” the Pi as a web-page to give authorization and then it is granted the “Offline” type of access, and so, the authentication lasts longer. The Pi-as-server, usually only ever serves one web-page, to one person, usually on the local network. You can call it an IoT device or a web-server, in the end it serves the same function.

Managing IoT Devices

I am not an expert in this field, but I understand that there are services designed for IoT devices, such as:

https://cloud.google.com/iot-core/

Essentially to manage IoT devices you can set up something like this:

enter image description here

The key part being the bit in the middle that will manage the user’s login information and access tokens. This will essentially be the “server” part that has “offline” access. Then this will query the Calendar API for the information and send it to the appropriate IoT device for that user.

This of course means keeping a database with the user info, access token, and which Raspberry Pi should be updated.

There are also PubSub services that act as a way to send messages between devices:

https://cloud.google.com/pubsub/

Please note: this does not mean that you have to manage the calendar information, all you need to do is to manage the logins, tokens and communication between the Calendar API and the Raspberry Pis.

Why can you do it on Android?

These types of applications work on android because you are logged in in a web-UI environment. Since you have already authorized your device, you can authorize apps through your device. Since you are not logged in with your Raspberry Pi, and you are in a CLI envionment you need to refresh the tokens.

Disclaimer

There may be a way to do what you want easily, but I don’t know it. If you find one, please add your own answer, I would be happy to read about it as I also have Raspberry Pis and this would be very interesting to me!

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement