PyDrive4 is a wrapper library of google-api-python-client that simplifies many common Google Drive API V3 tasks.
A modern, actively maintained Python library for Google Drive. Inspired by PyDrive and PyDrive2, rebuilt from scratch for Google Drive API V3 with simplified authentication and cleaner API.
PyDrive4 makes it easy to interact with Google Drive from Python. It wraps the google-api-python-client to provide a clean, intuitive API for common file and folder operations.
- Features
- Installation
- Quick Start
- Authentication Methods
- API Reference
- Usage Examples
- Advanced: GoogleAuth
- Error Handling
- Requirements
- π Multiple Auth Methods - ADC, OAuth2, Service Account with auto-detection
- π File Management - Upload, download, list, search files
- π Folder Operations - Create, list, search folders
- π Folder Upload - Upload entire directories recursively
- ποΈ Delete Operations - Trash or permanently delete items
- π Google Drive API v3 - Uses the latest API version
- β¨ Clean Error Messages - User-friendly one-line errors
pip install pydrive4Or with UV (recommended):
uv add pydrive4from pydrive4 import GoogleDrive
# Auto-authenticate (uses best available method)
client = GoogleDrive()
# List files
files = client.list_files()
print(f"Found {files['count']} files")PyDrive4 supports multiple authentication methods, ordered by recommendation:
| Method | Best For | Setup Required |
|---|---|---|
| 1. Application Default Credentials | Local dev, Google Cloud | gcloud CLI |
| 2. Service Account | Servers, automation, bots | JSON key file |
| 3. OAuth2 Client | Personal scripts, desktop apps | JSON + browser auth |
The easiest method for local development. No JSON files to manage!
-
Install Google Cloud SDK
-
Login with your Google account:
gcloud auth application-default login- That's it! Now just use:
from pydrive4 import GoogleDrive
client = GoogleDrive() # Works automatically!
files = client.list_files()ADC (Application Default Credentials) checks these locations in order:
GOOGLE_APPLICATION_CREDENTIALSenvironment variablegcloud auth application-default logincredentials- Google Cloud metadata service (on GCE, Cloud Run, etc.)
Best for servers, bots, and CI/CD pipelines. No user interaction needed.
Step 1: Create a Google Cloud Project
- Go to Google Cloud Console
- Click the project dropdown at the top β New Project
- Enter a project name (e.g., "My Drive App") β Create
- Wait for the project to be created, then select it
Step 2: Enable Google Drive API
- Go to APIs & Services β Library (or click here)
- Search for "Google Drive API"
- Click on it β Click Enable
Step 3: Create Service Account
- Go to IAM & Admin β Service Accounts (or click here)
- Click + Create Service Account
- Enter a name (e.g., "drive-bot") β Click Create and Continue
- Skip the optional steps β Click Done
Step 4: Create JSON Key
- Click on the service account you just created
- Go to the Keys tab
- Click Add Key β Create new key
- Select JSON β Click Create
- A JSON file downloads automatically
- Rename it to
service_account.jsonand move to your project folder
If you see this error:
An organisation policy that blocks service accounts key creation has been enforced
Policy: iam.disableServiceAccountKeyCreation
This means your organization has disabled service account key creation for security.
Solutions:
- Use OAuth2 instead (Method 3 below) - Recommended for personal use
- Use Application Default Credentials (Method 1) - Run
gcloud auth application-default login - Contact your admin to request an exception for the
iam.disableServiceAccountKeyCreationpolicy
from pydrive4 import GoogleDrive
# Auto-detect (if file is named service_account.json in current dir)
drive = GoogleDrive()
# Or explicit
drive = GoogleDrive(
credentials_name="service_account.json",
service_account=True
)| Aspect | OAuth2 | Service Account |
|---|---|---|
| Browser needed | Yes (first time) | No |
| Whose Drive? | Your personal Drive | Service account's own Drive |
| Best for | Personal scripts | Servers, automation |
| Access | All your files | Only files shared with it |
Important: Service accounts have their own empty Drive. To access your files, share folders with the service account email (e.g.,
my-bot@my-project.iam.gserviceaccount.com).
For desktop apps where you want to access your own Google Drive files. Opens browser once for authorization.
Step 1: Create a Google Cloud Project
- Go to Google Cloud Console
- Click the project dropdown at the top β New Project
- Enter a project name β Create
- Wait for the project to be created, then select it
Step 2: Enable Google Drive API
- Go to APIs & Services β Library
- Search for "Google Drive API"
- Click on it β Click Enable
Step 3: Configure OAuth Consent Screen
- Go to APIs & Services β OAuth consent screen
- Select External (or Internal if using Google Workspace) β Create
- Fill in required fields:
- App name: Your app name
- User support email: Your email
- Developer contact: Your email
- Click Save and Continue
- On Scopes page β Click Save and Continue
- On Test users page β Click Add Users β Add your email β Save and Continue
- Click Back to Dashboard
Step 4: Create OAuth Client ID
- Go to APIs & Services β Credentials
- Click + Create Credentials β OAuth client ID
- Application type: Desktop app
- Name: Any name (e.g., "PyDrive4")
- Click Create
- Click Download JSON (or the download icon)
- Rename to
client_secrets.jsonand move to your project folder
from pydrive4 import GoogleDrive
# Auto-detect (if file is in current directory)
drive = GoogleDrive()
# Or explicit
drive = GoogleDrive(credentials_name="client_secrets.json")First run: A browser window opens asking you to authorize the app. After authorizing, tokens are saved to token.json for future use (no browser needed again).
You can also set GOOGLE_APPLICATION_CREDENTIALS:
# Linux/macOS
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json"
# Windows PowerShell
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\credentials.json"
# Windows CMD
set GOOGLE_APPLICATION_CREDENTIALS=C:\path\to\credentials.jsonThen:
client = GoogleDrive() # Automatically uses the env variableWhen you call GoogleDrive() without arguments, it tries:
- Application Default Credentials (gcloud login or env variable)
- Service account files in current directory:
service_account.jsonservice_account_key.json
- OAuth2 files in current directory:
client_secrets.jsoncredentials.json
GoogleDrive(
credentials_name: str = None, # Path to credentials JSON
service_account: bool = None, # True/False/None (auto-detect)
token_file: str = "token.json", # Where to cache OAuth tokens
readonly: bool = False # Request read-only access
)| Method | Description | Returns |
|---|---|---|
list_files(folder_id, trashed) |
List files in a folder | {"success": bool, "files": list, "count": int} |
list_folders(parent_id, trashed) |
List folders | {"success": bool, "folders": list, "count": int} |
search_files(query, folder_id) |
Search files by name | {"success": bool, "files": list, "count": int} |
search_folders(query, parent_id) |
Search folders by name | {"success": bool, "folders": list, "count": int} |
get_folder(name, parent_id) |
Get folder by exact name | {"success": bool, "folder": dict, "found": bool} |
create_folder(name, parent_id, public) |
Create a folder | {"success": bool, "id": str, "link": str} |
upload_file(path, folder_id, overwrite, public) |
Upload a file | {"success": bool, "id": str, "link": str} |
download_file(file_id, output_path) |
Download a file | {"success": bool, "path": str, "size": int} |
upload_folder(path, parent_id) |
Upload folder recursively | {"success": bool, "files_uploaded": int} |
share(file_id, public, email, role) |
Share file/folder | {"success": bool, "link": str} |
unshare(file_id, email, remove_public) |
Remove sharing | {"success": bool, "removed_count": int} |
list_permissions(file_id) |
List who has access | {"success": bool, "permissions": list} |
get_share_link(file_id) |
Get shareable link | {"success": bool, "link": str, "is_public": bool} |
delete_file(file_id, permanently) |
Delete/trash a file | {"success": bool} |
delete_folder(folder_id, permanently) |
Delete/trash a folder | {"success": bool} |
from pydrive4 import GoogleDrive
client = GoogleDrive()
# List files in root
files = client.list_files()
for f in files["files"]:
print(f"π {f['name']}")
# List folders
folders = client.list_folders()
# List in specific folder
files = client.list_files(folder_id="folder_id_here")# Search files by name
results = client.search_files("report")
print(f"Found {results['count']} files")
# Search folders
folders = client.search_folders("Projects")# Create in root
folder = client.create_folder("My Folder")
print(f"Created: {folder['id']}")
# Create nested
parent = client.create_folder("Parent")
child = client.create_folder("Child", parent_id=parent["id"])# Upload to root
result = client.upload_file("document.pdf")
# Upload to folder
result = client.upload_file("report.pdf", folder_id="folder_id")
# Overwrite existing
result = client.upload_file("report.pdf", folder_id="folder_id", overwrite=True)# Download with custom path
result = client.download_file("file_id", "local.pdf")
# Download with original name
result = client.download_file("file_id")result = client.upload_folder("./my_project")
print(f"Uploaded {result['files_uploaded']} files")# Delete a file (move to trash)
drive.delete_file("file_id")
# Delete a file permanently
drive.delete_file("file_id", permanently=True)
# Delete a folder (move to trash)
drive.delete_folder("folder_id")
# Delete a folder permanently (deletes all contents!)
drive.delete_folder("folder_id", permanently=True)from pydrive4 import GoogleDrive
drive = GoogleDrive()
# Upload and make public in one call
result = drive.upload_file("document.pdf", public=True)
print(f"Share link: {result['link']}")
# Create a public folder
folder = drive.create_folder("Shared Files", public=True)
print(f"Folder link: {folder['link']}")
# Share with specific person
drive.share("file_id", email="colleague@example.com", role="writer")
# Make an existing file public
drive.share("file_id", public=True)
# Remove public access
drive.unshare("file_id", remove_public=True)
# Remove specific person's access
drive.unshare("file_id", email="colleague@example.com")
# Check who has access
perms = drive.list_permissions("file_id")
for p in perms["permissions"]:
print(f"{p.get('emailAddress', 'anyone')}: {p['role']}")
# Get shareable link
link_info = drive.get_share_link("file_id")
print(f"Link: {link_info['link']}, Public: {link_info['is_public']}")Most users don't need it! GoogleDrive() auto-authenticates for you.
| Approach | When to use |
|---|---|
drive = GoogleDrive() |
β Recommended - handles everything automatically |
auth = GoogleAuth() + GoogleDrive(auth=auth) |
Only for advanced control |
Use GoogleAuth directly when you need to:
- Check authentication status before operations
- Switch between multiple accounts
- Revoke tokens programmatically
- Get the raw Drive API service
from pydrive4 import GoogleAuth, GoogleDrive
# Create auth with specific credentials
auth = GoogleAuth(credentials_file="client_secrets.json")
auth.authenticate()
# Check status
print(f"Authenticated: {auth.is_authenticated}")
print(f"Using ADC: {auth.is_adc}")
print(f"Using Service Account: {auth.is_service_account}")
# Pass to drive client
drive = GoogleDrive(auth=auth)auth = GoogleAuth()
auth.authenticate()
# Later, revoke access and delete cached token
auth.revoke()For direct API access without the PyDrive4 wrapper:
from pydrive4 import GoogleAuth
auth = GoogleAuth()
auth.authenticate()
# Get the raw googleapiclient service
service = auth.get_drive_service()
# Use raw API
results = service.files().list(pageSize=10).execute()All methods return a dict with success key:
result = client.upload_file("document.pdf")
if result["success"]:
print(f"Uploaded: {result['id']}")
else:
print(f"Error: {result['error']}")Clean error messages:
β InvalidCredentialsError: No credentials available. Options:
1. Run: gcloud auth application-default login
2. Place 'client_secrets.json' in current directory
3. Set GOOGLE_APPLICATION_CREDENTIALS environment variable
- Python 3.10+
- google-api-python-client >= 2.100.0
- google-auth >= 2.15.0
- google-auth-oauthlib >= 1.0.0
- google-auth-httplib2 >= 0.2.0
MIT License
Contributions are welcome! Please submit a Pull Request.
Inspired by PyDrive2, updated for Google Drive API v3.