Python Google Drive API file retrieval with service account authentication issue

I’m having trouble with my Python script that downloads files from Google Drive using service account credentials.

I have a service account key file called auth_data.json in my project folder. My code looks like this:

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

auth_info = {"auth_data.json"}  # service account json data goes here

creds = service_account.Credentials.from_service_account_info(auth_info)
gdrive_api = build('drive', 'v3', credentials=creds)

document_id = 'my_file_ID'
api_request = gdrive_api.files().get_media(fileId=document_id)
file_handler = io.FileIO('downloaded_archive.tar.gz', 'wb')
download_handler = MediaIoBaseDownload(file_handler, api_request)
finished = False
while not finished:
    progress, finished = download_handler.next_chunk()
    print(f"Progress: {int(progress.progress() * 100)}%")

But I keep getting this error message:

Traceback (most recent call last):
  File "gdrive_downloader.py", line 9, in <module>
    creds = service_account.Credentials.from_service_account_info(auth_info)
  File "/usr/local/lib/python3.10/site-packages/google/oauth2/service_account.py", line 243, in from_service_account_info
    signer = _service_account_info.from_dict(
  File "/usr/local/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'

I tried creating a new service account key but still get the same error. What am I doing wrong here?

yeah, the problem’s in your auth_info line - ur using curly braces which creates a set, not a dict. either load the json file properly or just switch to from_service_account_file('auth_data.json') instead. way simpler and skips all the parsing headaches.

You’re declaring auth_info wrong. Those curly braces create a set with the string “auth_data.json” - but from_service_account_info() needs a dictionary with your actual service account data.

Load the JSON file properly first:

with open('auth_data.json', 'r') as f:
    auth_info = json.load(f)

Don’t forget to import json at the top. That’ll fix your authentication.

You’re passing a set object instead of the actual JSON data from your service account file. from_service_account_info() wants a dictionary with the credentials, not a filename. I hit this same issue when I started with Google Drive API. You need to read and parse the JSON file first. Better yet, just use from_service_account_file() which takes the file path directly: creds = service_account.Credentials.from_service_account_file('auth_data.json'). It’s cleaner since it handles the file reading for you. Also make sure your service account has permissions for the file you’re downloading.