1

Using Google Suite for Education.

I have an app that wants to:

  • Create a new calendar.
  • Add an ACL to such calendar, so the student role would be "reader".

Everything is run through a service account.

The calendar is created just fine, but inserting the ACL throws a 404 error (redacted for privacy):

<HttpError 404 when requesting https://www.googleapis.com/calendar/v3/calendars/MY_DOMAIN_long_string%40group.calendar.google.com/acl?alt=json returned "Not Found">

The function that tries to insert the ACL:

    def _create_calendar_acl(calendar_id, user, role='reader'):
        credentials = service_account.Credentials.from_service_account_file(
            CalendarAPI.module_path)
        scoped_credentials = credentials.with_scopes(
            ['https://www.googleapis.com/auth/calendar'])

        delegated_credentials = scoped_credentials.with_subject(
            'an_admin_email')

        calendar_api = googleapiclient.discovery.build('calendar',
                                                       'v3',
                                                       credentials=delegated_credentials)
        body = {'role': role,
                'scope': {'type': 'user',
                          'value': user}}

        answer = calendar_api.acl().insert(calendarId=calendar_id,
                                           body=body,
                                           ).execute()
        return answer

The most funny thing is, if I retry the operation a couple times, it finally succeeds. Hence, that's what my code does:

def create_student_schedule_calendar(email):
    MAX_RETRIES = 5
    # Get student information

    # Create calendar
    answer = Calendar.create_calendar('a.calendar.owner@mydomain',
                                      f'Student Name - schedule',
                                      timezone='Europe/Madrid')

    calendar_id = answer['id']

    counter = 0
    while counter < MAX_RETRIES:
        try:
            print('Try ' + str(counter + 1))
            _create_calendar_acl(calendar_id=calendar_id, user=email)  # This is where the 404 is thrown
            break
        except HttpError:  # this is where the 404 is caught
            counter += 1
            print('Wait ' + str(counter ** 2))
            time.sleep(counter ** 2)
            continue

    if counter == MAX_RETRIES:
        raise Exception(f'Exceeded retries to create ACL for {calendar_id}')

Anyway, it takes four tries (between 14 and 30 seconds) to succeed - and sometimes it expires.

Would it be possible that the recently created calendar is not immediately available for the API using it?

3
  • Would it be possible that the recently created calendar is not immediately available for the API using it? it's possible, propagation is something that comes hand in hand with cloud-stored data. After the first time your code works, do all operations that interact with the calendar work first time? Or do you still experience the same behaviour? Commented Jun 17, 2020 at 8:51
  • Thanks for your reply. As you suggest, that seems the case: all the operations on the new calendar succeed after that transient "Schrödinger" status. Actually, if memory serves me well, I found the calendar was not immediately available when playing with the API explorer: I was fast enough to create the calendar, copy its id, and using it to create the ACL. I left the API explorer open and, some minutes later, retried creating the ACL by clicking the EXECUTE button: it succeeded. Commented Jun 17, 2020 at 9:08
  • In this case yes, it's just pure propagation. I suggest if you're creating and editing in the same function call implementing some kind of wait/sleep for a moment to mitigate getting 404s. Commented Jun 17, 2020 at 10:21

1 Answer 1

1

Propagation is often an issue with cloud-based services. Large-scale online service are distributed along a network of machines which in themselves have some level of latency - there is a discrete, non-zero amount of time that information takes to propagate along a network and update everywhere.

All operations working after the first call which doesn't result in 404, is demonstrative of this process.

Mitigation:

I suggest if you're creating and editing in the same function call implementing some kind of wait/sleep for a moment to mitigate getting 404s. This can be done in python using the time library:

import time
# calendar creation code here
time.sleep(2)
# calendar edit code here
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.