Search code examples
pythongoogle-apigoogle-drive-apigoogle-api-python-clientservice-accounts

List Google Drive files and folders


I wanted to create a simple Python script to list files/folders recursively for a specific folder ID.

The following script works partially. As the starting folder, I used the ID "root" as this should be the root of Google Drive "My Drive".

from googleapiclient.discovery import build
from google.oauth2 import service_account

# Set up the Google Drive API service
scope = ['https://www.googleapis.com/auth/drive']
service_account_json_key = 'credentials.json'
credentials = service_account.Credentials.from_service_account_file(
    filename=service_account_json_key,
    scopes=scope)
service = build('drive', 'v3', credentials=credentials)

# Function to list files and folders recursively
def list_files_and_folders(folder_id, indent=""):
    results = service.files().list(
        q=f"'{folder_id}' in parents",
        fields="files(id, name, mimeType)").execute()
    items = results.get('files', [])

    if not items:
        print(indent + "No files or folders found.")
    else:
        for item in items:
            print(indent + f"{item['name']} ({item['id']}) - {item['mimeType']}")
            if item['mimeType'] == 'application/vnd.google-apps.folder':
                list_files_and_folders(item['id'], indent + "  ")

# Call the function to list files and folders starting from the specified folder ID
root_folder_id = 'root'
print(f"Listing files and folders recursively from root folder (ID: {root_folder_id}):")
list_files_and_folders(root_folder_id)

When I tried the script first, I didn't receive any results, and I have to admit I don't know why.

At the same time, I was also testing a Google Drive file upload script. This one I got from GitHub. I changed the parent's ID to "root", as I wanted the folder/file to be created under "My Drive".

from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from google.oauth2 import service_account

# Replace 'FOLDER_NAME' with the name you want to give your new folder
folder_name = 'Test Upload 2'

# setup google drive
credentials = service_account.Credentials.from_service_account_file(
        'credentials.json', scopes=['https://www.googleapis.com/auth/drive']
    )
service = build("drive", "v3", credentials=credentials)
folder_metadata = {
    'name': folder_name,
    "parents": ['root'],
    'mimeType': 'application/vnd.google-apps.folder'
}

# create folder 
new_folder = service.files().create(body=folder_metadata).execute()

#upload file inside the folder
file_metadata = {'name': 'image2.webp', 'parents': [new_folder['id']]}
media = MediaFileUpload('image2.webp')
file = service.files().create(body=file_metadata, media_body=media).execute()

# list the file inside of the folder
results = service.files().list(q=f"'{new_folder['id']}' in parents", fields="files(name)").execute()
items = results.get('files', [])
print(f"Files inside the folder , {items}")

The upload script worked without an issue, but when checking "My Drive" I couldn't spot the folder/file.

So I was running the script again to list the files and folders, and this time the script was "exclusively" returning the folder and file that had been created with the upload script, but nothing else from "My Drive".

  • How is this possible? Where was the folder/file uploaded?

  • Why I don't see them in My Drive?

  • Why is the script just listing the files I uploaded with the script but not the rest of My Drive?


Solution

  • When I tried the script first, I didn't receive any results, and I have to admit I don't know why.

    You are using a service account and start with its root folder are you sure it has any files uploaded to it?

    The upload script worked without an issue, but when checking "My Drive" I couldn't spot the folder/file.

    You are again using a service account you uploaded the file to the service accounts drive account not your own personal drive account your not going to see it.

    How is this possible? Where was the folder/file uploaded?

    The service accounts drive account

    Why I don't see them in My Drive?

    Because a service account is not you.

    Why is the script just listing the files I uploaded with the script but not the rest of My Drive?

    Because its listing the files on the service accounts drive account not your drive account.

    recursive listing files

    As a side note. Getting all of your files back by directory is going to require a lot of calls to the api at least one for every directory in your system. Your better bet would be to just use file.list and buffer everything locally and then sort it in to directories there. It will require fewer calls to the api.