pythongoogle-apigoogle-drive-apigoogle-oauth

Download files from Google Drive using Python and service account


I'm using a Python script to download a file from Google Drive using a specific file ID. To access the drive, I'm using an active key for a service account saved in the working directory as credentials.json.

from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
from google.oauth2 import service_account
import io

credz = {"credentials.json"} #json credentials here from service account

credentials = service_account.Credentials.from_service_account_info(credz)
drive_service = build('drive', 'v3', credentials=credentials)

file_id = 'file_ID'
request = drive_service.files().get_media(fileId=file_id)
#fh = io.BytesIO() # this can be used to keep in memory
fh = io.FileIO('file.tar.gz', 'wb') # this can be used to write to disk
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
    status, done = downloader.next_chunk()
    print("Download %d%%." % int(status.progress() * 100))

However I receive the following error whenever I run the program. I have tried a new JSON key, but remain unable to fix the error.

Traceback (most recent call last):
  File "Drive_Download.py", line 9, in <module>
    credentials = service_account.Credentials.from_service_account_info(credz)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/google/oauth2/service_account.py", line 243, in from_service_account_info
    signer = _service_account_info.from_dict(
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/google/auth/_service_account_info.py", line 47, in from_dict
    missing = keys_needed.difference(data.keys())
AttributeError: 'set' object has no attribute 'keys'

Solution

  • I think that you might need to load credentials.json as a dictionary in python because it ix expecting a dictionary but you instead are passing a set.

    This addition to code might work:

    import json
    with open("credentials.json", "r") as f:
        credz = json.load(f)