Pydrive error: No downloadLink/exportLinks for mimetype found in metadata

12.8k views Asked by At

I am trying to download a simple text file from google drive automatically with the pydrive module for python. I keep getting the following error:

Traceback (most recent call last): File "C:\GIS\AVGOPS\Scripts\GoogleDrive_Test.py", line 20, in item.GetContentFile(r'C:\Users\pfilyer\Desktop\googedrive\' + item['title']) File "C:\Python27\ArcGIS10.4\lib\site-packages\pydrive\files.py", line 210, in GetContentFile self.FetchContent(mimetype, remove_bom) File "C:\Python27\ArcGIS10.4\lib\site-packages\pydrive\files.py", line 43, in _decorated return decoratee(self, *args, **kwargs) File "C:\Python27\ArcGIS10.4\lib\site-packages\pydrive\files.py", line 265, in FetchContent 'No downloadLink/exportLinks for mimetype found in metadata') FileNotDownloadableError: No downloadLink/exportLinks for mimetype found in metadata

Any suggestions?

import pydrive
from pydrive.drive import GoogleDrive

from pydrive.auth import GoogleAuth

gauth = GoogleAuth()
gauth.LoadCredentialsFile(r"C:\Users\XXXXX\.credentials\drive-python-quickstart.json")
drive = GoogleDrive(gauth)

print "Auth Success"

folder_id = '0BxbuUXtrs7adSFFYMG0zS3VZNFE'
lister = drive.ListFile({'q': "'%s' in parents" % folder_id}).GetList()
for item in lister:
    print item['title']
    item.GetContentFile(r'C:\Users\XXXXX\Desktop\googedrive\\' +    item['title'])
4

There are 4 answers

1
TomasDostal On

You are possibly trying to download a google document, spreadsheet or whatever else which is not a ordinary file.

I got exactly the same error a few moments ago, when I tried to download a file of mimeType: application/vnd.google-apps.document. The document has to be exported to other format before downloading. Check this:

import pydrive
from pydrive.drive import GoogleDrive

from pydrive.auth import GoogleAuth

gauth = GoogleAuth()
gauth.LoadCredentialsFile(r"C:\Users\XXXXX\.credentials\drive-python-    quickstart.json")
drive = GoogleDrive(gauth)

print "Auth Success"

folder_id = '0BxbuUXtrs7adSFFYMG0zS3VZNFE'
lister = drive.ListFile({'q': "'%s' in parents" % folder_id}).GetList()
for item in lister:
    print(item['title'])
    # this should tell you which mimetype the file you're trying to download 
    # has. 
    print('title: %s, mimeType: %s' % (item['title'], item['mimeType']))
    mimetypes = {
        # Drive Document files as PDF
        'application/vnd.google-apps.document': 'application/pdf',

        # Drive Sheets files as MS Excel files.
        'application/vnd.google-apps.spreadsheet': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

    # see https://developers.google.com/drive/v3/web/mime-types
    }
    download_mimetype = None
    if file['mimeType'] in mimetypes:
        download_mimetype = mimetypes[file['mimeType']]
        file.GetContentFile(file['title'], mimetype=download_mimetype)

        item.GetContentFile(r'C:\Users\XXXXX\Desktop\googedrive\\' + item['title'], mimetype=download_mimetype)
    else: 
        item.GetContentFile(r'C:\Users\XXXXX\Desktop\googedrive\\' + item['title'])

This should work.

0
Damzaky On

In my case it was because there was multiple files with the same name and extension but different ID, I removed one and the code works

0
KarthikS On

When you upload documents to google drive, make sure the 'Convert documents to Google docs editor format option is unchecked in google drive settings. This ensures that your uploaded file is in the same format as the one in your local (e.g., .csv, .txt, etc.). For me, this worked.

enter image description here

1
rassi On

Built from the examples in this thread, here a script which walks through all subfolders of a gdrive folder and downloads folderstructure and all files within. Takes care of gdrive docs, spreadsheets and presentations. Logs if a file fails :)

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
import os

gauth = GoogleAuth()
gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth)

MIMETYPES = {
        # Drive Document files as MS dox
        'application/vnd.google-apps.document': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        # Drive Sheets files as MS Excel files.
        'application/vnd.google-apps.spreadsheet': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        # Drive presentation as MS pptx
        'application/vnd.google-apps.presentation': 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
        # see https://developers.google.com/drive/v3/web/mime-types
    }
EXTENSTIONS = {
        'application/vnd.google-apps.document': '.docx',
        'application/vnd.google-apps.spreadsheet': '.xlsx',
        'application/vnd.google-apps.presentation': '.pptx'
}

f = open("failed.txt","w+")
folder_id = '<folder_id_from_browser_address_bar>'
root = 'drive_download'
os.mkdir(root)

def escape_fname(name):
    return name.replace('/','_')

def search_folder(folder_id, root):
    file_list = drive.ListFile({'q': "'%s' in parents and trashed=false" % folder_id}).GetList()
    for file in file_list:
        # print('title: %s, id: %s, kind: %s' % (file['title'], file['id'], file['mimeType']))
        # print(file)
        if file['mimeType'].split('.')[-1] == 'folder':
            foldername = escape_fname(file['title'])
            create_folder(root,foldername)
            search_folder(file['id'], '{}{}/'.format(root,foldername))
        else:
            download_mimetype = None
            filename = escape_fname(file['title'])
            filename = '{}{}'.format(root,filename)
            try:
                print('DOWNLOADING:', filename)
                if file['mimeType'] in MIMETYPES:
                    download_mimetype = MIMETYPES[file['mimeType']]

                    file.GetContentFile(filename+EXTENSTIONS[file['mimeType']], mimetype=download_mimetype)
                else:
                    file.GetContentFile(filename)
            except:
                print('FAILED')
                f.write(filename+'\n')

def create_folder(path,name):
    os.mkdir('{}{}'.format(path,escape_fname(name)))

search_folder(folder_id,root+'/')
f.close()