To make requests to Google APIs the work flow is in essence the following:
- Go to developer console, log in if you haven't.
- Create a Cloud Platform project.
- Enable for your project, the APIs you are interested in using with you projects' apps (for example: Google Drive API).
- Create and download OAuth 2.0 Client IDs credentials that will allow your app to gain authorization for using your enabled APIs.
- Head over to OAuth consent screen, click on
and add your scope using the
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. - 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)
- 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.
- If consent is given, your app will receive an authorization token.
- Pass the token in your request to your authorized API endpoints.[2]
- 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:
- 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)
- 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)
Answer from Aerials on Stack OverflowTo make requests to Google APIs the work flow is in essence the following:
- Go to developer console, log in if you haven't.
- Create a Cloud Platform project.
- Enable for your project, the APIs you are interested in using with you projects' apps (for example: Google Drive API).
- Create and download OAuth 2.0 Client IDs credentials that will allow your app to gain authorization for using your enabled APIs.
- Head over to OAuth consent screen, click on
and add your scope using the
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. - 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)
- 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.
- If consent is given, your app will receive an authorization token.
- Pass the token in your request to your authorized API endpoints.[2]
- 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:
- 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)
- 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)
I usually do it using two files for modularity:
gdrive_credentials.py
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
import os
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/drive.readonly'] # Or drive if you need write access
def get_credentials(credentials_json = "credentials.json", token_json = "token.json"):
"""Gets or creates Google Drive API credentials.
Args:
credentials_json: The filename of the credentials file.
token_json: The filename of the token file
Returns:
A Credentials object, or None if an error occurred.
"""
creds = None
if os.path.exists(token_json):
creds = Credentials.from_authorized_user_file(token_json, SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
try:
creds.refresh(Request())
except Exception as e: # Catch exceptions during refresh
print(f"Error refreshing credentials: {e}")
return None
else:
if not os.path.exists(credentials_json):
print(f"Credentials file '{target}' not found. Please download it from Google Cloud Console.")
return None
flow = InstalledAppFlow.from_client_secrets_file(credentials_json, SCOPES)
try:
creds = flow.run_local_server(port=0)
except Exception as e: # Catch exceptions during auth flow
print(f"Error during authorization flow: {e}")
return None
with open(token_json, 'w') as token_file:
token_file.write(creds.to_json())
return creds
if __name__ == '__main__':
_ = get_credentials()
gdrive_wget.py
import google_auth_oauthlib.flow
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
import io
import shutil
def download_file_from_drive(file_id, output_filename, drive_service):
try:
file_metadata = drive_service.files().get(fileId=file_id, fields='mimeType, name').execute()
mime_type = file_metadata.get('mimeType')
file_name = file_metadata.get('name')
print(f"Downloading file: {file_name} (Mime Type: {mime_type})")
if mime_type == 'application/vnd.google-apps.document':
request = drive_service.files().export(fileId=file_id, mimeType='text/plain')
elif mime_type == 'application/vnd.google-apps.spreadsheet':
request = drive_service.files().export(fileId=file_id, mimeType='text/csv') # Example for Sheets
elif mime_type == 'application/vnd.google-apps.presentation':
request = drive_service.files().export(fileId=file_id, mimeType='application/pdf') # Example for Slides
else:
request = drive_service.files().get_media(fileId=file_id)
# Download the file into RAM
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(output_target, 'wb') as f:
shutil.copyfileobj(fh, f, length=131072)
except HttpError as error:
print(f'An HTTP error occurred: {error}')
except Exception as e:
print(f'A general error occurred: {e}')
return None
if __name__ == '__main__':
import scryb_credentials
credentials = scryb_credentials.get_credentials()
drive_service = build('drive', 'v3', credentials=credentials)
import sys
file_id = sys.argv[1]
output_target = sys.argv[2]
download_file_from_drive(file_id, output_target, drive_service)
python: How do i download a file from Google drive using api - Stack Overflow
Python: download files from google drive using url - Stack Overflow
Downloading A File with Google Drive API - Stack Overflow
Google Drive API downloading files with Python - Stack Overflow
Videos
just write the content variable to a file instead of returning the content
fo = open("foo.jpg", "wb")
fo.write(content)
fo.close()
I think you should probably check out this:
http://pythonhosted.org/PyDrive/
The code seems like it is easier
# Initialize GoogleDriveFile instance with file id.
file6 = drive.CreateFile({'id': file5['id']})
file6.GetContentFile('catlove.png') # Download file as 'catlove.png'.
# Initialize GoogleDriveFile instance with file id.
file7 = drive.CreateFile({'id': file4['id']})
content = file7.GetContentString()
# content: '{"firstname": "Claudio", "lastname": "Afshar"}'
If by "drive's url" you mean the shareable link of a file on Google Drive, then the following might help:
import sys
import requests
def download_file_from_google_drive(file_id, destination):
URL = "https://docs.google.com/uc?export=download&confirm=1"
session = requests.Session()
response = session.get(URL, params={"id": file_id}, stream=True)
token = get_confirm_token(response)
if token:
params = {"id": file_id, "confirm": token}
response = session.get(URL, params=params, stream=True)
save_response_content(response, destination)
def get_confirm_token(response):
for key, value in response.cookies.items():
if key.startswith("download_warning"):
return value
return None
def save_response_content(response, destination):
CHUNK_SIZE = 32768
with open(destination, "wb") as f:
for chunk in response.iter_content(CHUNK_SIZE):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
def main():
if len(sys.argv) >= 3:
file_id = sys.argv[1]
destination = sys.argv[2]
else:
file_id = "TAKE_ID_FROM_SHAREABLE_LINK"
destination = "DESTINATION_FILE_ON_YOUR_DISK"
print(f"dowload {file_id} to {destination}")
download_file_from_google_drive(file_id, destination)
if __name__ == "__main__":
main()
The snipped does not use pydrive, nor the Google Drive SDK, though. It uses the requests module (which is, somehow, an alternative to urllib2).
When downloading large files from Google Drive, a single GET request is not sufficient. A second one is needed - see wget/curl large file from google drive.
I recommend the gdown package.
pip install gdown
Take your share link
https://drive.google.com/file/d/0B9P1L--7Wd2vNm9zMTJWOGxobkU/view?usp=sharing
and grab the id - eg. 1TLNdIufzwesDbyr_nVTR7Zrx9oRHLM_N by pressing the download button (look for at the link), and swap it in after the id below.
import gdown
url = 'https://drive.google.com/uc?id=0B9P1L--7Wd2vNm9zMTJWOGxobkU'
output = '20150428_collected_images.tgz'
gdown.download(url, output, quiet=False)
I don't know the documentation page you're mentioning but, in order to download a file, get its metadata and make an authenticated request to its downloadUrl.
f = service.files().get(fileId=file_id).execute()
resp, content = service._http.request(f.get('downloadUrl'))
You might consider trying the Temboo Python SDK, which contains simplified methods for working with Google Drive (in addition to 100+ other APIs). Take a look at https://www.temboo.com/library/Library/Google/Drive/Files/Get/
(Full disclosure: I work at Temboo.)
» pip install PyDrive