Search code examples
google-apigoogle-drive-apigoogle-api-python-clientgoogle-client

Google Drive v3 API: Get Shared Drive 404 but List Drives Works


So, I have the below code to get a specific Google Shared Drive by its id:

import os.path

from google.oauth2 import service_account # see: https://stackoverflow.com/a/64509140/497745 and https://developers.google.com/identity/protocols/oauth2/service-account#authorizingrequests
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from googleapiclient.http import MediaFileUpload

SCOPES = ["https://www.googleapis.com/auth/drive"]
SERVICE_ACCOUNT_FILE = "credentials.json"

def main():

  creds = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)        

  try:
        drive_api_service = build("drive", "v3", credentials=creds)

        # see: https://googleapis.github.io/google-api-python-client/docs/dyn/drive_v3.drives.html#get
        folder = (drive_api_service.drives()
          .get(driveId="1AEZqVMFTv9qTVp7QVA", useDomainAdminAccess=True)  
          .execute())

  except Exception as error:
        print(f'An error occurred: {error}')

if __name__ == "__main__":
  main()

Note: For security reasons, I've manually changed the drive ID. But I know the ID is valid because I'm getting it from the result of successfully calling: drive_api_service.drives().list().execute() with the same service account.

My service account is in a different Google Cloud account than the Google Workspace with the Shared Drive.

However, I've:

  1. Added my service account for Domain Wide Delegation.
  2. Added my service account, via its email address, as a Content Manager to the shared drive.
  3. I've turned on "Allow users outside XXX to access files in shared drives"

The shared drive has no folders.

My service account is able to list the shared drive with no problems.

{'kind': 'drive#driveList', 'drives': [{'id': '1AEZqVMFTv9qTVp7QVA', 'name': 'dcf_results', 'kind': 'drive#drive'}]}

However, when I try to get the drive with the above code, I get a 404.

An error occurred: <HttpError 404 when requesting https://www.googleapis.com/drive/v3/drives/0ADQqULDEv5pYUk9PVA?useDomainAdminAccess=true&alt=json returned "Shared drive not found: 0ADQqULDEv5pYUk9PVA". Details: "[{'message': 'Shared drive not found: 1AEZqVMFTv9qTVp7QVA', 'domain': 'global', 'reason': 'notFound', 'location': 'driveId', 'locationType': 'parameter'}]">

I've noticed that I've had to jump through a ton of obscure hoops to make sure the service account has all of the settings ticked, and access added to even get to where I could list the shared drive via my service account in the external Google Workspace account.

So, my guess is:

  1. There is some obscure setting or permission I've missed that allows the service account to do more than list Shared Drives in the external Google Workspace
  2. I'm making the get call incorrectly. Maybe I can't get a shared drive directly by its Id, only a folder under that shared drive.

Any ideas?


Solution

  • In your situation, how about removing useDomainAdminAccess=True from folder = (drive_api_service.drives().get(driveId="1AEZqVMFTv9qTVp7QVA", useDomainAdminAccess=True).execute())?

    When I saw the official document of useDomainAdminAccess of "Method: drives.get", it says as follows.

    Issue the request as a domain administrator; if set to true, then the requester will be granted access if they are an administrator of the domain to which the shared drive belongs.

    I guessed that this might be the reason for your current issue. So, how about removing it as follows?

    From:

    folder = (drive_api_service.drives()
      .get(driveId="1AEZqVMFTv9qTVp7QVA", useDomainAdminAccess=True)  
      .execute())
    

    To:

    folder = (drive_api_service.drives()
      .get(driveId="1AEZqVMFTv9qTVp7QVA")
      .execute())
    

    Reference: