How to save downloaded data from Google Drive in file – Python Drive API

Question:

I need download a file from my google drive, after some tests with python i got the data downloaded from the drive like the google documentation says (https://developers.google.com/drive/api/v3/quickstart/python), (https://developers.google.com/drive/api/v3/manage-downloads#downloading_a_file), but i don’t know how to save this “data” in a file.

How can i do that?

This is my code

from __future__ import print_function
import pickle
import os.path
import io
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.http import MediaIoBaseDownload

SCOPES = ['https://www.googleapis.com/auth/drive']

creds = None

if os.path.exists('token.pickle'):
    with open('token.pickle', 'rb') as token:
        creds = pickle.load(token)

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)

file_id = '1ZR7MpJe9KQliuICCv-5iae6DeGQzHaTB'
request = 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(status)
    print ("Download %d%%." % int(status.progress() * 100))

this is the result with my code

API DRIVE

Asked By: davids182009

||

Answers:

  • You want to save the downloaded file as a file to the local PC.
  • You want to achieve this using google-api-python-client with Python.
  • You have already been able to get and put the file using Drive API.

If my understanding is correct, how about this modification?

From:

fh = io.BytesIO()

To:

fh = io.FileIO("### filename ###", mode='wb')

References:

If this was not the result you want, I apologize.

Answered By: Tanaike

Install gshell on github, really useful

Answered By: monkeyking9528

Just to add to the accepted answer, if the file ID is not known, the following code searches for files of the required type to retrieve the ID and then downloads to local machine:

from __future__ import print_function
import pickle
import os.path
import io
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.http import MediaIoBaseDownload

SCOPES = ['https://www.googleapis.com/auth/drive']

creds = None

if os.path.exists('token.pickle'):
    with open('token.pickle', 'rb') as token:
        creds = pickle.load(token)

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)


page_token = None
while True:
    response = service.files().list(q="mimeType='image/tiff'",
                                          spaces='drive',
                                          fields='nextPageToken, files(id, name)',
                                          pageToken=page_token).execute()
    for file in response.get('files', []):
        # Process change
        print('Found file: %s (%s)' % (file.get('name'), file.get('id')))
        file_id = file.get('id')
        file_nm = file.get('name')
    page_token = response.get('nextPageToken', None)
    if page_token is None:
        break


print('Downloading ',file_nm)
request = service.files().get_media(fileId=file_id)
fh = io.FileIO('myout1.tiff',mode='wb')
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
    status, done = downloader.next_chunk()
    print(status)
    print ("Download %d%%." % int(status.progress() * 100))

Hope this helps

Answered By: shahryar

Just create a new file and pass the handle to MediaIoBaseDownload:

with io.FileIO(fileName, "wb") as fh:
    downloader = MediaIoBaseDownload(fh, request)
    done = False
    while done is False:
        status, done = downloader.next_chunk()
        print(f"Download {status.progress()*100}%.")
Answered By: Scissor Lee