In order to download a .mp4 file from my Drive, started using Google Drive API with target CLI tool which required to create new credentials.
Then, when downloading a file belonging to a user that only sent me the link using Google Drive API,
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import io
from googleapiclient.http import MediaIoBaseDownload
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive.file']
def main():
"""Shows basic usage of the Drive v3 API.
Prints the names and ids of the first 10 files the user has access to.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('drive', 'v3', credentials=creds)
# Call the Drive v3 API to download the file
file_id = '1ZVFrwYaLClNrIk6TkshJZamHSS-59LLR'
request = service.files().get_media(fileId=file_id)
filename = "test.mp4"
#fh = io.BytesIO()
fh = io.FileIO(filename, 'wb') # From - https://stackoverflow.com/a/40309675/5675325
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print("Download %d%%." % int(status.progress() * 100))
if __name__ == '__main__':
main()
I got the following error
File "C:\Users\tiago\Anaconda3\lib\site-packages\googleapiclient\http.py", line 749, in next_chunk
raise HttpError(resp, content, uri=self._uri)
HttpError: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files/1ZVFrwYaLClNrIk6TkshJZamHSS-59LLR?alt=media returned "The user has not granted the app 682654872192 read access to the file 1ZVFrwYaLClNrIk6TkshJZamHSS-59LLR.">
This isn't someting new (even though it might be a misleading error message) and is described in their documentation as
Resolve a 403 error: The user has not granted the app {appId} {verb} access to the file {fileId}
which states that
An appNotAuthorizedToFile error occurs when your app is not on the ACL for the file.
...
To fix this error, perform one of the following operations:
Open the Google Drive picker and prompt the user to open the file.
Instruct the user to use your app to open the file using the Open with context menu in the Drive UI.
You can also check the isAppAuthorized field on a file to see if the file was created by or opened with your app.
How to go over this and download the file?
In order to solve it, I've just gone through the following two steps.
Change scope to drive
- as suggested here and here.
SCOPES = ['https://www.googleapis.com/auth/drive']
Delete token.pickle and run the script again - as suggested here.
Then, manage to download the file and it works fine.