How to download a file from Google Drive using Python and the Drive API v3

Solution 1:

To make requests to Google APIs the work flow is in essence the following:

  1. Go to developer console, log in if you haven't.
  2. Create a Cloud Platform project.
  3. Enable for your project, the APIs you are interested in using with you projects' apps (for example: Google Drive API).
  4. Create and download OAuth 2.0 Client IDs credentials that will allow your app to gain authorization for using your enabled APIs.
  5. Head over to OAuth consent screen, click on enter image description here and add your scope using the enter image description here button. (scope: https://www.googleapis.com/auth/drive.readonly for you). Choose Internal/External according to your needs, and for now ignore the warnings if any.
  6. To get the valid token for making API request the app will go through the OAuth flow to receive the authorization token. (Since it needs consent)
  7. During the OAuth flow the user will be redirected to your the OAuth consent screen, where it will be asked to approve or deny access to your app's requested scopes.
  8. If consent is given, your app will receive an authorization token.
  9. Pass the token in your request to your authorized API endpoints.[2]
  10. Build a Drive Service to make API requests (You will need the valid token)[1]

NOTE:

The available methods for the Files resource for Drive API v3 are here.

When using the Python Google APIs Client, then you can use export_media() or get_media() as per Google APIs Client for Python documentation


IMPORTANT:

Also, check that the scope you are using, actually allows you to do what you want (Downloading Files from user's Drive) and set it accordingly. ATM you have an incorrect scope for your goal. See OAuth 2.0 API Scopes


Sample Code References:

  1. Building a Drive Service:
import google_auth_oauthlib.flow
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
 
 
class Auth:
 
    def __init__(self, client_secret_filename, scopes):
        self.client_secret = client_secret_filename
        self.scopes = scopes
        self.flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(self.client_secret, self.scopes)
        self.flow.redirect_uri = 'http://localhost:8080/'
        self.creds = None
 
    def get_credentials(self):
        flow = InstalledAppFlow.from_client_secrets_file(self.client_secret, self.scopes)
        self.creds = flow.run_local_server(port=8080)
        return self.creds

 
# The scope you app will use. 
# (NEEDS to be among the enabled in your OAuth consent screen)
SCOPES = "https://www.googleapis.com/auth/drive.readonly"
CLIENT_SECRET_FILE = "credentials.json"
 
credentials = Auth(client_secret_filename=CLIENT_SECRET_FILE, scopes=SCOPES).get_credentials()
 
drive_service = build('drive', 'v3', credentials=credentials)
  1. Making the request to export or get a file
request = drive_service.files().export(fileId=file_id, mimeType='application/pdf')

fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
    status, done = downloader.next_chunk()
    print("Download %d%%" % int(status.progress() * 100))

# The file has been downloaded into RAM, now save it in a file
fh.seek(0)
with open('your_filename.pdf', 'wb') as f:
    shutil.copyfileobj(fh, f, length=131072)