Download Google Drive files via API (including Google Sheets, etc.)
Published: 2024-03-08 09:29:08

> The following content is automatically translated. If there are any errors, please contact me.

These days, I need to download Google Sheets through an API, but it turns out to be quite troublesome and there isn't much information available. Therefore, I'm recording the process here.

## 1. Basic code
First, let me provide an example file called [sample Spreadsheet.xlsx] (https://docs.google.com/spreadsheets/d/1JI17N-NFAIOxX_2Y88gmuKMlsuGhBPcB/edit#gid=1677858863). Assuming that we need to download this file, the basic code required is as follows:

```python
import io
import os
from typing import List
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.http import MediaIoBaseDownload


def run(file_id: str, save_path: str, credentials_path: str, scopes: List[str]):
    creds = None
    if os.path.exists("token.json"):
        creds = Credentials.from_authorized_user_file("token.json", scopes)
    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_path, scopes)
            creds = flow.run_local_server(port=0)
        with open("token.json", "w") as token:
            token.write(creds.to_json())

    service = build("drive", "v3", credentials=creds)

    # Different files require different download method, and I don't know how to distinguish them at the moment, so I can only try another one after an error
    # Export：Docs Editors files
    # Get：files with binary content
    try:
        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("Download %d%%." % int(status.progress() * 100))
    except Exception:
        request = service.files().export(
            fileId=file_id, mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        )
        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))

    with open(save_path, "wb") as f:
        fh.seek(0)
        f.write(fh.read())


if __name__ == "__main__":
    file_id = "1JI17N-NFAIOxX_2Y88gmuKMlsuGhBPcB"
    save_path = "Sample Spreadsheet.xlsx"
    scopes = ["https://www.googleapis.com/auth/drive"]
    credentials_path = "credentials.json"
    run(file_id, save_path, credentials_path, scopes)
```

Install dependencies

```shell
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
```

To execute the above code, we need to obtain a crucial credentials file called **credentials.json**. This is Google's credentials file, and accessing Google Drive files requires passing through Google's authorization check, which verifies if you have the permission to access the resource. Below is a guide on how to obtain this file.

## 2. Create a new project

To create a credential file, you first need to create a project in [Google Cloud Console](https://console.cloud.google.com). If you already have a project, you can use it directly.

![Create a new project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3j9hi5j7vzuvwq04ozv.png)

## 3. Enable the Google Cloud Drive API service

> Since Google Sheets actually exists on Google Drive, we only need the Google Drive API here. If you need to access and modify the cell data of a spreadsheet, you can enable the Google Sheets API service.

After creating a new project, select it and click on **Enable API & Services**. Find the **Google Drive API** and click on **Enable** to grant the project access to call Google Drive services.

![Enable the Google Cloud Drive API service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/snage9mvevkv3wzmkvbb.png)

## 4. Create credentials

After enabling it, go back to the main page and click on **Credentials**. Select **OAuth Client ID**.

![OAuth Client ID](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ef63li3hujrtbqe8umhn.png)

## 5. Config consent screen

For a newly created project, you will need to configure consent screen before creating credentials. Click on **Configure Consent Screen**.

![Configure Consent Screen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9ghqhqaco694k8p8kls.png)

**User Type** can only be external

![User Type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nt5ynuize73yuhw8dif.png)

Fill in your email address. You can use your own Google email address for the other email fields.

![Fill in your email 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/un0aol625heux8eisblw.png)

![Fill in your email 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfykzs2w46rl06a9a6al.png)

## 6. Select the scope of authorization

Since I only need to download files, I have only selected **drive.readonly** here. If you need to perform other operations, select the corresponding scope.

![drive.readonly](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pwnm9sgjtus76fusishd.png)

![save scope](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0opvi1aamsl2ts37yf50.png)

**Test users** can continue to use your own Google email addresses.

![add test users](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9qyxwsbt5c27i6nlflt.png)

At this point, the consent screen is completely configured.

## 7. Generate credentials.json file
Go back to step 4, create the credentials again, and select the **Desktop app**

![Desktop app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/whq908dux97g69xzo81l.png)

![download json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kvo0w5elfu2kxufel1jm.png)
Just download and rename the file to **credentials.json**

## 8. Run code
The first time you run the code, you need to log in with your account password to generate a **token.json** file. After that, you won't need to log in again (as long as it hasn't expired). This is a personal application you created yourself, so there's no need to worry about security issues.

![log in](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5f0nrcivpgkqv3uaakzg.png)

![auth app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/62ay0y1b0e7eon10mdss.png)
## 9. Check out results
After waiting for the terminal output, you can see that it has been downloaded.
```text
Download 100%.
```
If you find that the downloaded file does not sync the cloud modification records, it is usually because the editor is still on the page and needs to save and exit, and then download it again to sync the latest editing results.