Setting Up fsspec for Google Drive with a Service Account
Table of Contents
- Why a Service Account?
- Set Up a Google Cloud Project
- Create a Service Account
- Create a JSON Key
- Share Your Drive Folder
- Install Dependencies
- Connect with fsspec
- Read and Write Files
- Using as an fsspec Backend
- Final Thoughts
Why a Service Account?
The standard OAuth2 flow for Google Drive requires a browser-based login, caches refresh tokens that can expire, and breaks on headless machines. A service account eliminates all of that:
- No browser required — authentication uses a static JSON key
- No token expiry — service account keys don’t expire (unless you rotate them)
- No credential cache — no stale tokens under
~/.cache/pydrive2fs/ - CI/CD friendly — works in pipelines, containers, and remote servers
Set Up a Google Cloud Project
Before creating a service account, you need a Google Cloud project with the Drive API enabled. Follow the first two steps of the PyDrive2 Quickstart:
- Go to Google APIs Console and create a new project (or select an existing one)
- Search for Google Drive API, select the entry, and click Enable
These two steps give your project permission to make Drive API calls. Without this, requests will fail with a 403 Drive API has not been used error.
Create a Service Account
- In the same project, go to IAM & Admin > Service Accounts
- Click + CREATE SERVICE ACCOUNT
- Enter a name (e.g.
pydrive2-sa) and click CREATE AND CONTINUE - Skip the optional “Grant access” steps and click DONE
You’ll see the service account listed with an email like:
pydrive2-sa@your-project.iam.gserviceaccount.com
Take note of this email - you’ll need it to share your Drive folder.
Create a JSON Key
- Click on the service account you just created
- Go to the KEYS tab
- Click ADD KEY > Create new key
- Select JSON and click CREATE
- A
.jsonfile downloads automatically
Move it to a secure location in your project:
mv ~/Downloads/your-project-xxxxxx.json ./service-account-key.json
Warning: This key grants access to any Drive resources shared with the service account. Keep it out of version control (add it to
.gitignore).
Share Your Drive Folder
The service account is a separate Google identity - it can only access files and folders explicitly shared with it.
- Open Google Drive in your browser
- Right-click the folder you want to access > Share
- Paste the service account email (e.g.
pydrive2-sa@your-project.iam.gserviceaccount.com) - Set the permission level (Viewer for read-only, Editor for read/write)
- Click Send
To find the folder ID, open the folder in Drive and copy the ID from the URL:
https://drive.google.com/drive/folders/<this_is_the_folder_id>
Install Dependencies
pip install pydrive2[fsspec]
Connect with fsspec
from pydrive2.auth import GoogleAuth
from pydrive2.fs import GDriveFileSystem
def connect(folder_id, key_file):
"""Connect to a Google Drive folder using a service account."""
settings = {
"client_config_backend": "service",
"service_config": {
"client_json_file_path": key_file,
},
}
gauth = GoogleAuth(settings=settings)
gauth.ServiceAuth()
return GDriveFileSystem(folder_id, google_auth=gauth)
key_file = "./service-account-key.json"
folder_id = "<this_is_the_google_drive_folder_id>"
fs = connect(folder_id, key_file)
That’s it - no browser popup, no cached tokens.
Read and Write Files
List files
for root, dirs, files in fs.walk(folder_id):
for d in dirs:
print(f"dir: {root}/{d}")
for f in files:
print(f"file: {root}/{f}")
Read a file
import json
with fs.open(f"{folder_id}/config.json", "r") as f:
data = json.load(f)
print(data)
Write a file
with fs.open(f"{folder_id}/output.json", "w") as f:
json.dump({"status": "ok"}, f)
Use with pandas
import pandas as pd
with fs.open(f"{folder_id}/data.csv", "r") as f:
df = pd.read_csv(f)
print(df.head())
Using as an fsspec Backend
PyDrive2’s GDriveFileSystem is an fsspec-compatible filesystem, but it does not auto-register itself with fsspec. To use it through the standard fsspec.filesystem and fsspec.open APIs, you need to register it first:
import fsspec
from pydrive2.fs import GDriveFileSystem
fsspec.register_implementation("gdrive2", GDriveFileSystem)
After registration, you can use the standard fsspec API:
fs = fsspec.filesystem(
"gdrive2",
path="<this_is_the_google_drive_folder_id>",
use_service_account=True,
client_json_file_path="./service-account-key.json",
)
folder_id = "<this_is_the_google_drive_folder_id>"
# List all entries in the folder
entries = fs.ls(folder_id)
for entry in entries:
print(entry)
Open files using fsspec.open:
import json
with fsspec.open(
f"gdrive2://{folder_id}/config.json",
"r",
use_service_account=True,
client_json_file_path="./service-account-key.json",
) as f:
data = json.load(f)
print(data)
Registering a Custom Implementation
You can also subclass GDriveFileSystem to inject default credentials or add custom behavior, then register under your own protocol name:
import fsspec
from pydrive2.auth import GoogleAuth
from pydrive2.fs import GDriveFileSystem
class MyDriveFileSystem(GDriveFileSystem):
"""GDrive filesystem that authenticates with a service account by default."""
protocol = "mydrive"
def __init__(self, path, key_file="./service-account-key.json", **kwargs):
settings = {
"client_config_backend": "service",
"service_config": {
"client_json_file_path": key_file,
},
}
gauth = GoogleAuth(settings=settings)
gauth.ServiceAuth()
super().__init__(path, google_auth=gauth, **kwargs)
fsspec.register_implementation("mydrive", MyDriveFileSystem)
# Callers only need the folder ID
fs = fsspec.filesystem("mydrive", path=folder_id)
entries = fs.ls(folder_id)
This keeps authentication details out of calling code and lets you swap backends by changing the protocol string.
Final Thoughts
A service account is the simplest way to connect to Google Drive programmatically. There’s no browser flow, no token cache, and no expiring refresh tokens. It works the same on your laptop, in a notebook, and in a CI/CD pipeline.
The only requirement is sharing the target folder with the service account email. After that, it’s just connect(folder_id, key_file).