How to move a file in a shared google drive to trash using a service account

1k views Asked by At

I use a service account that is content-manager. I have no problem uploading files to the shared drive using the drive-api from python. Using

service.files().list(q="name='file_name'", fields="files(id)").execute() 

I obtain the file_id from my code. This file_id is the right one based on the link to the file.

When I perform the following statement:

response = service.files().update(fileId=file_id, body={'trashed': True}).execute()

I get a

404: file not found.

How to resolve this ? With my personal account (also as content-manager) I have no problems trashing the file.

1

There are 1 answers

0
Jose Vasquez On BEST ANSWER

Requirements

If you clearly understand how to impersonate an account you can skip to the Solution step.

Solution

By default Python Google Drive API client V3 doesn't include shared drive files, that's why you have to explicitly pass a parameter supportsAllDrives and set it to True and before that you should list your files in order to know the fileId parameter by using includeItemsFromAllDrives and supportsAllDrives. Here's an example to list all the files in all your drives and how to trash a file in a Shared Drive using a service account:

from googleapiclient.discovery import build
from google.oauth2 import service_account

SCOPES = ['https://www.googleapis.com/auth/drive']
SERVICE_ACCOUNT_FILE = './service_account_key.json'

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

# Impersonate [email protected] account in my example.com domain
delegated_credentials = credentials.with_subject('[email protected]')

# Use the delegated credentials to impersonate the user
service = build('drive', 'v3', credentials=delegated_credentials)

# List all the files in your Drives (Shared Drives included)
results = service.files().list(fields="nextPageToken, files(id, name, trashed)", includeItemsFromAllDrives=True, supportsAllDrives=True).execute()
items = results.get('files', [])

if not items:
    print('No files found.')
else:
    print('Files:')
    for item in items:
        print(u'{0} ({1}) - Trashed? {2}'.format(item['name'], item['id'], item['trashed']))

# Use the filedId in order to trash your shared file
response = service.files().update(fileId=fileId, body={'trashed': True}, supportsAllDrives=True).execute()
print(response)

Otherwise if you already know the fileId just use the update part.

Reference

Python Google Drive API client V3 > Update a file

Google Identity Platform > Impersonate a user by using a service account