How to Download File from Google Drive API with Service Account

Google Drive Authenticate and Download Files with Service Account

Daily Limit for Unauthenticated Use Exceeded.

This error message is normally the result of not applying the authorization credentials in your code. I couldn't spot any issues off the bat with your code though. The first thing i would like to suggest is that you double check that you have service account credentials added in your project and not the wrong type. However i would have expected a different error message if this was the issue.

Try this its based upon the offical samples manage downloads

from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials

SCOPES = ['https://www.googleapis.com/auth/drive']
KEY_FILE_LOCATION = '<REPLACE_WITH_JSON_FILE>'

def initialize_drive():
"""Initializes an drive service object.

Returns:
An authorized drive service object.
"""
credentials = ServiceAccountCredentials.from_json_keyfile_name(
KEY_FILE_LOCATION, SCOPES)

# Build the service object.
service = build('drive', 'v3', credentials=credentials)

return service

def download_report(drive_service, id):
file_id = '0BwwA4oUTeiV1UVNwOHItT0xfa2M'
request = drive_service.files().get_media(fileId=file_id)
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)
return fh

only files with binary content can be downloaded

Remember there are two types of files on drive. Google drive mimetype files which need to be downloaded using the export method and all other binary type files. Binary files are downloaded using the method you are using now.

def main():
service = initialize_drive()

buffer = download_report(service, <file_id>)

if __name__ == '__main__':
main()

Export method

file_id = '1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo'
request = drive_service.files().export_media(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)

Download Google Drive file owned by some account and shared with my service account

What you need to understand is that if someone else has access to your file then its private data. You need the permission of the owner of the flie to access it. Using a service account you can preauthorize it and grant it access to the file. If that person shares the file with the service account email address like you would share it with any other user then then and only then will the service account have access to download the file.

Is that a correct choice and how to authenticate to the app without password?

The only way you can get access to private user data is if the user grants you access. You can use Oauth2 and ask the user to run your application and grant you access, or you can use a service account and pre authorize it to access the data.

There is really no way to gain access to private user data without them granting you that access somehow. Client login used login and password and that was shut down by google in 2015 so that hasn't worked in years.

Exporting a sheet with a service account.

You are correct this is not done by downloading a url this is done by using the file.id of the file you wish to download.

As you will be downloading a google sheet your going to want to do a file.export to download the flie. File export will convert your sheet to a csv file so that you can read it on your machine.

Just make sure that you shared it with the service account.

const {google} = require('googleapis');

const auth = new google.auth.GoogleAuth({
keyFile: '/path/to/your-secret-key.json',
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
});

var fileId = '1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo';
var dest = fs.createWriteStream('/tmp/resume.pdf');
drive.files.export({
fileId: fileId,
mimeType: 'application/pdf'
})
.on('end', function () {
console.log('Done');
})
.on('error', function (err) {
console.log('Error during download', err);
})
.pipe(dest);

How to download file from google drive api with service account?

The answer is simple - we cannot download it from file object, we must send another get request, just download it like this:

drive.get_file(file.id, download_dest: '/tmp/my_file.txt')

Get download link of file in Service Account Google API

Remember that a service account is not you. A service account is a dummy user you are uploading files to the service accounts Google drive account. The files it uploads will then be owned by it.

The file resource should contain one of these links. You can use them to show the file to another user.

  • Link a user to a file — webContentLink from the file resource (download)
  • Link a user to a file - webViewLink form file resource (will open in the Google drive website)

webViewLink string A link for opening the file in a relevant Google editor or viewer in a browser.

webContentLink string A link for downloading the content of the file in a browser. This is only available for files with binary content in Drive.

You may have to either have the service account set the file to public or share it with you before you will be able to use either of those links. check Permissions

Downloading a google drive file without sharing it with service account

A service account is not you, think of it as a dummy user account.

You file on google drive is private user data owned by you. If you want me to be able to download your file you need to share it with me, the same goes for the service account.

With Oauth2 a window pops up asking the user to grant the application access to the data, service accounts are pre authorized by sharing things with them manually.

A service account cant download files it does not have access to. You need to share the file with it for it to be able to access it.

Creating a file with Google Drive API using a Service Account doesn't render file on authorized user account's GD

You have four options...

  1. Don't use a Service Account. Just store a Refresh Token for the User Account. See How do I authorise an app (web or installed) without user intervention? . It's a myth that Service Accounts are the only option for Server access.
  2. Use a Service Account to write to a folder which has been shared by your User Account to the Service Account
  3. Use a Service Account to write to a folder which is shared by your Service Account to your User Account
  4. Use a Service Account within a G-Suite domain to impersonate the User Account

Option 1. is the easiest, 2 and 3 only differ in terms of who owns the files and therefore against whose quota they are counted. 4 is only relevant for G-Suite



Related Topics



Leave a reply



Submit