'Error downloading a file from Google Drive

I exported some images from Google Earth Engine to Google Drive. I need to download those images to a local drive using a Python script. Then, I tried to use oauth2client, apiclient as I saw here:

I got a list of files in Drive and the corresponding IDs, then I use the ID to try to download the file using the gdown lib:

gdown.download(f'https://drive.google.com/uc?id={file_data["id"]}',
                       f'{download_path}{os.sep}{filename_to_download}.tif')

I got the following error message:

Access denied with the following error:
    Cannot retrieve the public link of the file. You may need to change
    the permission to 'Anyone with the link', or have had many accesses. 
You may still be able to access the file from the browser:
     https://drive.google.com/uc?id=<id> 

As I got the Drive file list, I suppose that the Drive authentication is ok. If I use the error message suggested link in the browser, I can download the file. If a check file properties at Drive, I can see:

Who can access: not shared.

What should I do to download the files?

This is the complete code:

# https://medium.com/swlh/google-drive-api-with-python-part-i-set-up-credentials-1f729cb0372b
# https://levelup.gitconnected.com/google-drive-api-with-python-part-ii-connect-to-google-drive-and-search-for-file-7138422e0563
# https://stackoverflow.com/questions/38511444/python-download-files-from-google-drive-using-url
import os
from apiclient import discovery
from httplib2 import Http
from oauth2client import client, file, tools
import gdown

class GoogleDrive(object):
    # define API scope
    def __init__(self, secret_credentials_file_path = './credentials'):
        self.DriveFiles = None
        SCOPE = 'https://www.googleapis.com/auth/drive'
        self.store = file.Storage(f'{secret_credentials_file_path}{os.sep}credentials.json')
        self.credentials = self.store.get()
        if not self.credentials or self.credentials.invalid:
            flow = client.flow_from_clientsecrets(f'{secret_credentials_file_path}{os.sep}client_secret.json',
                                                  SCOPE)
            self.credentials = tools.run_flow(flow, self.store)
        oauth_http = self.credentials.authorize(Http())
        self.drive = discovery.build('drive', 'v3', http=oauth_http)

    def RetrieveAllFiles(self):
        results = []
        page_token = None

        while True:
            try:
                param = {}

                if page_token:
                    param['pageToken'] = page_token

                files = self.drive.files().list(**param).execute()
                # append the files from the current result page to our list
                results.extend(files.get('files'))
                # Google Drive API shows our files in multiple pages when the number of files exceed 100
                page_token = files.get('nextPageToken')

                if not page_token:
                    break

            except Exception as error:
                print(f'An error has occurred: {error}')
                break
        self.DriveFiles = results

    def GetFileData(self, filename_to_search):
        for file_data in self.DriveFiles:
            if file_data.get('name') == filename_to_search:
                return file_data
        else:
            return None

    def DownloadFile(self, filename_to_download, download_path):
        file_data = self.GetFileData(f'{filename_to_download}.tif')
        gdown.download(f'https://drive.google.com/uc?id={file_data["id"]}',
                       f'{download_path}{os.sep}{filename_to_download}.tif')



Solution 1:[1]

Google drive may not be the best tool for this, you may want to upload them into a RAW file hosting service like Imgur and download it to a file using requests, you can then read the file using the script or you don't even have to write it to the file and just use image.content instead to specify the image. Here's an example:

image = requests.get("https://i.imgur.com/5SMNGtv.png")
with open("image.png", 'wb') as file:
    file.write(image.content)

(You can specify the location of where you want the file to download by adding the PATH before the file name, like this:)

image = requests.get("https://i.imgur.com/5SMNGtv.png")
with open("C://Users//Admin//Desktop//image.png", 'wb') as file:
    file.write(image.content)

Solution 2:[2]

Solution 1.

Access denied with the following error:
 Cannot retrieve the public link of the file. You may need to change
 the permission to 'Anyone with the link', or have had many accesses. 
You may still be able to access the file from the browser:
 https://drive.google.com/uc?id=<id> 

In the sharing tab on gdrive (Right click on image, open Share or Get link), please change privacy to anyone with the link. Hopefully your code should work. Step 2 Step 1

Solution 2.

If you can use Google Colab, then you can mount gdrive easily and access files there using

from google.colab import drive
drive.mount('/content/gdrive')

Solution 3:[3]

Google has this policy that they do not accept your regular google-/gmail-password. They only accept so called "App Passwords" that you need to create for your google-account in order to authenticate if you are using thirdparty apps

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ron Vermann
Solution 2 Rahul Chauhan
Solution 3 reenhilm