Google Drive makes it very easy to share files. You can easily and securely share files to anyone with a Google account or to anyone else by creating a shareable link that is accessible to anyone that knows the link. The shareable link contains a 33 character random string, so it’s very difficult to guess the URL if you are worried about someone other than your intended recipient looking at the shared file.
Despite shareable links being very difficult to guess, it’s the simple fact that they are public that requires an audit every once in a while to see what files are shared and remove public access if necessary.
I don’t know why, but the Google Drive web interface does not make it easy to find all shared files. There have been plenty of requests for this feature on the Google Drive Help Forum over the years (1, 2, 3), but the feature still does not exist.
There are third-party options out there such as Drive Permissions Auditor or WhoHasAccess, but those options cost money and require trusting a third-party to access your Google Drive.
I wanted an easy to understand script completely controlled by me that shows all the files I am currently sharing from Google Drive regardless if those files are shared to people with Google accounts or to anyone via a shareable link.
Because of Wesley Chun’s series of blog posts (1, 2), I was able to quickly piece together a Python script to list all files in my Google Drive and then make some modifications to show only the files that are shared.
The remainder of the post will walk you through everything needed to run the Python script.
Google Developer and Credential Setup
Go to the Google Developers Console and login with the Google account associated with your Google Drive. You might be prompted to accept an updated Terms of Services.
You will need to create a Project to enable the Google Drive API. If you don’t already have a Project, click the Create Project button and follow the instructions.
Once you have created a Project, enable the Google Drive API, and click the Create Credentials button.
You will more than likely need to configure the OAuth consent screen first. Click the Configure consent screen button and fill out the Product name shown to users text field. Since you are the only person accessing your own private data, you can input whatever text string you want. Click Save when you are finished.
After clicking Save, you will be prompted for the following:
- Which API are you using? Select Google Drive API
- Where will you be calling the API from? Select Other UI (e.g. Windows, CLI tool)
- What data will you be accessing? Select User data
Then, click the What credentials do I need? button.
Give the OAuth 2.0 client ID a name such as google-drive-list-shared.py, and click the Create OAuth client ID button.
Click the Download button to download the client_id.json file that will be used by the Python script.
Finally, click the Done button.
Download the Python Script
Create directory google-drive-list-shared and change into it:
mkdir ~/Downloads/google-drive-list-shared
cd google-drive-list-shared
Create file google-drive-list-shared.py with the following Python script:
#!/usr/bin/env python
from __future__ import print_function
import time
import ast
from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
SCOPES = 'https://www.googleapis.com/auth/drive.readonly.metadata'
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('client_id.json', SCOPES)
creds = tools.run_flow(flow, store)
service = discovery.build('drive', 'v3', http=creds.authorize(Http()))
results = service.files().list(
pageSize=1000,
fields="nextPageToken, files(name, shared)").execute()
token = results.get('nextPageToken', None)
items = results.get('files', [])
while token is not None:
results = service.files().list(
pageSize=1000,
pageToken=token,
fields="nextPageToken, files(name, shared)").execute()
# Store the new nextPageToken on each loop iteration
token = results.get('nextPageToken', None)
# Append the next set of results to the items variable
items.extend(results.get('files', []))
# Google Drive does not return valid JSON because the property
# names are not enclosed in double quotes, they are enclosed in
# single quotes. So, use Python AST to convert the string to an
# iterable list.
items_dict = ast.literal_eval(str(items))
print("You have", len(items_dict), "files in Google Drive\n")
print("The following files are shared:\n")
# Iterate through the items list and only show files that have
# shared set to True.
for i in range(len(items_dict)):
if items_dict[i]['shared']:
print(items_dict[i]['name'])
Create file requirements.txt with the following contents:
google-api-python-client
oauth2client
Move the client_id.json from earlier into this directory:
mv ~/Downloads/client_id.json .
Create a Python virtual environment:
virtualenv env
source env/bin/activate
Install the Python requirements:
pip install -r requirements.txt
Run the Python Script
If you are running the Python script from your workstation, run the following command. Your web browser will open and require you to allow the Python script read access to your Google Drive:
python google-drive-list-shared.py
If you are running the Python script from a virtual machine without a GUI or web browser, run the following command instead and follow the prompted instructions:
python google-drive-list-shared.py --noauth_local_webserver
Once authenticated, the Python script will begin running and display only the files in your Google Drive that are shared to anyone with a Google account or to anyone else via a shareable link. The Python script might take a while to run if you have a lot of files saved in Google Drive.