Last active
January 29, 2018 19:58
-
-
Save ninapavlich/73e86a5f1db591d93d56220ec50783db to your computer and use it in GitHub Desktop.
Retrieve list of files in a given folder with Google Drive API (v3) + Requests + ServiceAccountCredentials
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import json | |
import urllib | |
import requests | |
from oauth2client.service_account import ServiceAccountCredentials | |
from django.core.management.base import BaseCommand, CommandError | |
class Command(BaseCommand): | |
""" | |
NOTE: In this example I have encapsulated the example in a Django command, but you can easily extract the contents from the handle() function to run this elsewhere. | |
""" | |
def handle(self, *args, **options): | |
""" | |
Basic overview for using Google Drive API with Python + Requests + oauth2client.ServiceAccountCredentials: | |
1) Create API project Auth 2.0 Client credentials. Download Auth 2.0 JSON credentials and save to file. Credentials can be downloaded though dashboard Google APIs -> APIs & Services -> Credentials -> OAuth 2.0 client IDs -> Download JSON | |
Try going here to see a list of your API projects: https://console.developers.google.com/apis/credentials/oauthclient/ | |
Example | |
{ | |
"type": "service_account", | |
"project_id": "my-project-id", | |
"private_key_id": "XXXXXXX PRIVATE KEY ID HERE XXXXXXX", | |
"private_key": "-----BEGIN PRIVATE KEY-----\n XXXXXXX private key values here XXXXXXX =\n-----END PRIVATE KEY-----\n", | |
"client_email": "my-client-name@my-project-id.iam.gserviceaccount.com", | |
"client_id": "XXXXXXX CLIENT ID HERE XXXXXXX", | |
"auth_uri": "https://accounts.google.com/o/oauth2/auth", | |
"token_uri": "https://accounts.google.com/o/oauth2/token", | |
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | |
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/my-client-name%40my-project-id.iam.gserviceaccount.com" | |
} | |
2) Locate your folder or file in Google Drive and share it with the email address listed above in the "client_email" field -- such as my-client-name@my-project-id.iam.gserviceaccount.com | |
3) Generate auth credentials using ServiceAccountCredentials.from_json_keyfile_name(CREDS_FILE_PATH, SCOPE) | |
4) Use requests.Session() with the auth credentials to authorize requests to the API | |
""" | |
CREDS_ROOT = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir, os.pardir, os.pardir, os.pardir)) | |
CREDS_FILE_PATH = '%s/creds-google.json' % CREDS_ROOT | |
SCOPE = [ | |
'https://www.googleapis.com/auth/drive', | |
'https://www.googleapis.com/auth/drive.file', | |
'https://www.googleapis.com/auth/drive.readonly', | |
'https://www.googleapis.com/auth/drive.metadata.readonly', | |
'https://www.googleapis.com/auth/drive.metadata' | |
] | |
credentials = ServiceAccountCredentials.from_json_keyfile_name(CREDS_FILE_PATH, SCOPE) | |
FOLDER_NAME = 'My Fancy Folder' | |
FOLDER_ID = None #We're going to figure this out through the API | |
# EXAMPLE QUERIES: | |
# -------------------- | |
# Get a folder matching a name: mimeType = 'application/vnd.google-apps.folder' and name = 'match-my-name' | |
# Get a file matching a name: mimeType != 'application/vnd.google-apps.folder' and name = 'match-my-name' | |
# Get files in a folder: 'XXXXXX-MY-FOLDER-ID-XXXXXX' in parents | |
# Get files in a folder matching a name: 'XXXXXX-MY-FOLDER-ID-XXXXXX' in parents and name = 'match-my-name' | |
# Create requests session object (avoids need to pass in headers with every request) | |
session = requests.Session() | |
session.headers = { 'Authorization' : 'Bearer ' + credentials.get_access_token().access_token } | |
# A. Find folder by name to get folder UUID: | |
folder_query = u"mimeType = 'application/vnd.google-apps.folder' and name = '%s'"%(FOLDER_NAME) | |
folder_params = { | |
'includeTeamDriveItems': "true", | |
'supportsTeamDrives': "true", | |
'q': folder_query | |
} | |
folder_params_encoded = urllib.urlencode(folder_params) | |
folder_info_response = session.get(u"https://www.googleapis.com/drive/v3/files?%s"%(folder_params_encoded)) | |
folder_response_data = folder_info_response.json() | |
""" | |
If the folder has been found, the response JSON will look something like this: | |
-------------------- | |
{ | |
"kind": "drive#fileList", | |
"incompleteSearch": false, | |
"files": [ | |
{ | |
"kind": "drive#file", | |
"id": "XXXXX MY FOLDER ID HERE XXXXX", | |
"name": "My folder name", | |
"mimeType": "application/vnd.google-apps.folder" | |
} | |
] | |
} | |
""" | |
if "files" in folder_response_data and len(folder_response_data["files"]) > 0: | |
FOLDER_ID = folder_response_data["files"][0]["id"] | |
# B. Find all files in the folder: | |
files_in_folder_query = u"'%s' in parents"%(FOLDER_ID) | |
file_params = { | |
'includeTeamDriveItems': "true", | |
'supportsTeamDrives': "true", | |
'q': files_in_folder_query | |
} | |
file_params_encoded = urllib.urlencode(file_params) | |
file_info_response = session.get(u"https://www.googleapis.com/drive/v3/files?%s"%(file_params_encoded)) | |
file_response_data = file_info_response.json() | |
""" | |
If the folder contains files, the response JSON will look something like this: | |
-------------------- | |
{ | |
"kind": "drive#fileList", | |
"incompleteSearch": false, | |
"files": [ | |
{ | |
"kind": "drive#file", | |
"id": "XXXXX MY FILE ID HERE XXXXX", | |
"name": "my-image.jpg", | |
"mimeType": "image/jpeg" | |
}, | |
{ | |
"kind": "drive#file", | |
"id": "XXXXX MY FILE ID HERE XXXXX", | |
"name": "my-spreadsheet.xlsx", | |
"mimeType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | |
} | |
] | |
} | |
""" | |
print u"Found %s files in folder %s [%s]"%(len(file_response_data["files"]), FOLDER_NAME, FOLDER_ID) | |
else: | |
print u"Could not find folder with name %s"%(FOLDER_NAME) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment