2

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

davids182009
  • 441
  • 3
  • 7
  • 26
  • Does this answer your question? [How to download a Google Drive file using Python and the Drive API v3](https://stackoverflow.com/questions/60111361/how-to-download-a-google-drive-file-using-python-and-the-drive-api-v3) – RayB Aug 24 '20 at 18:42

4 Answers4

6
  • 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.

Tanaike
  • 181,128
  • 11
  • 97
  • 165
1

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

shahryar
  • 121
  • 5
0

Install gshell on github, really useful

0

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}%.")
  • 1
    While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Adrian Mole Sep 17 '22 at 21:51