Wrapper for Google's Python API
Project description
googleapiutils2
Python wrapper for Google APIs: Drive, Sheets, Gmail, Admin, Groups, Geocoding.
Installation
via pip
pip install googleapiutils2
via uv
uv add googleapiutils2
Requires Python ^3.12
Overview
googleapiutils2 provides a unified, Pythonic interface for Google APIs with built-in:
- Automatic retry - 10 retries with exponential backoff
- TTL caching - 80s cache on frequently accessed data
- Request throttling - Rate limiting to prevent quota exhaustion
- Type hints - Full IDE support via google-api-stubs
- URL support - Accept file/sheet IDs or URLs interchangeably
Quick Start
Drive
from googleapiutils2 import Drive, GoogleMimeTypes
drive = Drive()
# Upload
drive.upload("file.csv", to_mime_type=GoogleMimeTypes.sheets, parents=["folder_id"])
drive.upload("./folder", recursive=True, update=True)
# List
for file in drive.list(query="name contains 'report'"):
print(f"{file['name']}: {file['id']}")
# Download
drive.download("file_id", "./output.pdf", mime_type=GoogleMimeTypes.pdf)
drive.download("folder_id", "./local_folder", recursive=True)
Sheets
from googleapiutils2 import Sheets, SheetsValueRange
sheets = Sheets()
Sheet1 = SheetsValueRange(sheets, sheet_url, "Sheet1")
# Slice notation (NumPy-like)
Sheet1[1, "A"].update([["Value"]])
Sheet1[2:5, 1:3].update([[1,2,3], [4,5,6], [7,8,9]])
data = Sheet1[...].read()
# Batch updates
sheets.batch_update(sheet_url, {
Sheet1[1, ...]: [["Header 1", "Header 2"]],
Sheet1[2:4, ...]: [[1, 2], [3, 4]]
})
# DataFrame integration
import pandas as pd
df = Sheet1[...].to_frame()
Sheet1.update(sheets.from_frame(df, include_header=True))
# Formatting
sheets.format(sheet_url, Sheet1[1, ...], bold=True, background_color="#d48686")
from googleapiutils2 import Mail
mail = Mail()
# Send email
mail.send(
sender="me@example.com",
to="user@example.com",
subject="Test",
body="Hello"
)
# List messages
for msg in mail.list_messages(query="from:user@example.com after:2024/01/01"):
print(msg['id'], msg['snippet'])
Admin (Workspace)
from googleapiutils2 import Admin
admin = Admin()
# Create user
user = admin.create_user(
primary_email="test@domain.com",
given_name="Test",
family_name="User",
password="temp123"
)
# List users
for user in admin.list_users(query="givenName:John"):
print(user['primaryEmail'])
Groups
from googleapiutils2 import Groups
groups = Groups()
# Create group
group = groups.create(
email="team@domain.com",
name="Engineering",
description="All engineers"
)
# Add members
groups.members_insert("team@domain.com", "user@domain.com")
for member in groups.members_list("team@domain.com"):
print(member['email'], member['role'])
Geocode
from googleapiutils2 import Geocode
geocoder = Geocode(api_key="YOUR_API_KEY")
# Address to coordinates
results = geocoder.geocode("1600 Amphitheatre Parkway, Mountain View, CA")
print(results[0]['geometry']['location']) # {'lat': 37.422, 'lng': -122.084}
# Coordinates to address
results = geocoder.reverse_geocode(lat=37.422, long=-122.084)
Monitor (Change Detection)
from googleapiutils2 import SheetsMonitor
def on_change(data, monitor):
print(f"Sheet updated: {len(data)} rows")
monitor = SheetsMonitor(sheets, drive, sheet_url, on_change, interval=30)
monitor.start()
Authentication
Two authentication methods supported:
Service Account (Recommended for automation)
When to use:
- Automated scripts and server applications
- No user interaction needed
- Domain-wide delegation (Workspace only)
Setup:
- Enable APIs: https://console.cloud.google.com/apis/library
- Create Service Account: https://console.cloud.google.com/iam-admin/serviceaccounts
- Download JSON key file
Usage:
from googleapiutils2 import Drive, get_oauth2_creds
# Basic service account
creds = get_oauth2_creds(client_config="auth/service-account.json")
drive = Drive(creds=creds)
# With domain-wide delegation (Workspace only)
creds = get_oauth2_creds(client_config="auth/service-account.json")
creds = creds.with_subject("user@domain.com") # Impersonate user
drive = Drive(creds=creds)
OAuth2 Client (For user authorization)
When to use:
- Desktop applications
- User consent required
- Personal Google accounts
Setup:
- Enable APIs: https://console.cloud.google.com/apis/library
- Create OAuth Client: https://console.cloud.google.com/apis/credentials/oauthclient (Desktop app)
- Configure consent screen: https://console.cloud.google.com/apis/credentials/consent
Usage:
# First run: opens browser for authorization
# Token saved to auth/token.pickle for reuse
creds = get_oauth2_creds(
client_config="auth/oauth2_credentials.json",
token_path="auth/token.pickle"
)
drive = Drive(creds=creds)
Auto-discovery
# Auto-discovery checks ./auth/credentials.json or GOOGLE_API_CREDENTIALS env var
drive = Drive()
sheets = Sheets()
Features
Drive
Upload:
- Files, folders (recursive)
- DataFrames to Google Sheets
- Markdown ↔ Google Docs conversion
- MD5 checksum for skip-if-unchanged
Download:
- Files, folders (recursive)
- Format conversion (Sheets → xlsx, Docs → docx, etc.)
- Chunked downloads for large files
Operations:
get,list,create,copy,update,deletesync- Sync local ↔ remote directoriesempty_trash- Empty trash- Permissions management
Sheets
Slice Notation:
Sheet[1, "A"] # Single cell
Sheet[2:5, 1:3] # Range
Sheet[1, ...] # Entire row
Sheet[..., "A"] # Entire column
Sheet[-1, -1] # Last cell
Sheet["A1:B2"] # A1 notation
Operations:
- CRUD: create, read, update, delete, append, clear
- Formatting: bold, colors, alignment, wrap, freeze
- Batch updates with auto-chunking
- Column alignment for dict data
- Auto-resize on overflow
DataFrame Integration:
df = Sheet1[...].to_frame()
Sheet1.update(sheets.from_frame(df, include_header=True))
Messages:
- Send (plain text, HTML)
- Create drafts
- List, get, modify, trash, delete
Labels:
- List, create, delete, modify
- Apply/remove labels from messages
Admin (Workspace)
User Management:
- Create, update, delete users
- Suspend/unsuspend accounts
- Password management
- Admin role management
- Search by name, email, org unit
Groups
Group Operations:
- Create, update, delete groups
- List groups by domain/customer/user
Member Operations:
- Add, remove, update members
- List members
- Check membership
- Role management (OWNER, MANAGER, MEMBER)
Geocode
Operations:
- Forward geocoding (address → coordinates)
- Reverse geocoding (coordinates → address)
- Address component parsing
- Location type (ROOFTOP, RANGE_INTERPOLATED, etc.)
Architecture
Base Class: DriveBase - All API classes inherit (except Geocode)
- TTL caching (80s, 128 entries)
- Retry decorator (10 retries, 30s delay, exponential backoff)
- Throttling (0.1s individual, 1s batch)
- Background request queueing
Exception Hierarchy:
GoogleAPIException
├── InvalidRequestError
├── OverQueryLimitError
├── RequestDeniedError
├── NotFoundError
└── UnknownError
Key Patterns:
- TYPE_CHECKING blocks for circular import prevention
- Generator pattern for pagination
- MIME type auto-detection and conversion
- MD5 checksum caching
- Slice notation for Sheets (NumPy-like)
File Structure
googleapiutils2/
├── utils/ # Core: DriveBase, auth, caching, retry, MIME types
├── drive/ # Google Drive API
├── sheets/ # Google Sheets API
├── mail/ # Gmail API
├── admin/ # Workspace Admin API
├── groups/ # Google Groups API
├── geocode/ # Maps Geocoding API
└── monitor.py # Change detection (DriveMonitor, SheetsMonitor)
Dependencies
- google-api-python-client ^2.168.0
- google-auth ^2.39.0
- google-auth-oauthlib ^1.2.1
- pandas ^2.2.3
- cachetools ^5.5.2
- loguru ^0.7.3
- requests ^2.32.3
Testing
pytest test/
Tests use real Google APIs with session-scoped fixtures and automatic cleanup.
Documentation
- Project Overview: CLAUDE.md
- Utils Module: googleapiutils2/utils/CLAUDE.md
- Drive Module: googleapiutils2/drive/CLAUDE.md
- Sheets Module: googleapiutils2/sheets/CLAUDE.md
- Mail Module: googleapiutils2/mail/CLAUDE.md
- Admin Module: googleapiutils2/admin/CLAUDE.md
- Groups Module: googleapiutils2/groups/CLAUDE.md
- Geocode Module: googleapiutils2/geocode/CLAUDE.md
Examples
See examples/ for more usage patterns:
drive_upload.py- File/folder uploadssheets_crud.py- Sheet operations and formattingmail.py- Email sendingmonitor.py- Change detection- And more...
License
MIT
Repository
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file googleapiutils2-0.20.0.tar.gz.
File metadata
- Download URL: googleapiutils2-0.20.0.tar.gz
- Upload date:
- Size: 56.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8f8b9e738f704dfd092d4bf263801ab03cae0fb5f15b91619b019c1be853248
|
|
| MD5 |
9a30143b6458334ebe893c4010b164af
|
|
| BLAKE2b-256 |
ed4bb703375e94ade1d0baa598bdfa2acc4a4ec10cb6b2e1b1b032d098ee6f4c
|
Provenance
The following attestation bundles were made for googleapiutils2-0.20.0.tar.gz:
Publisher:
publish.yml on mkbabb/googleapiutils2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
googleapiutils2-0.20.0.tar.gz -
Subject digest:
b8f8b9e738f704dfd092d4bf263801ab03cae0fb5f15b91619b019c1be853248 - Sigstore transparency entry: 701338902
- Sigstore integration time:
-
Permalink:
mkbabb/googleapiutils2@3f02b24535aff70a3b771b4716a4482f0b4bab6e -
Branch / Tag:
refs/heads/master - Owner: https://github.com/mkbabb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3f02b24535aff70a3b771b4716a4482f0b4bab6e -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file googleapiutils2-0.20.0-py3-none-any.whl.
File metadata
- Download URL: googleapiutils2-0.20.0-py3-none-any.whl
- Upload date:
- Size: 67.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ecb8fbcf1b018adc6bfb3aa7805e16ddc4a983f95732d22a01a75bdc6c68daa6
|
|
| MD5 |
91d8e9d60aa7ad26d6bf1cee3c74eb2f
|
|
| BLAKE2b-256 |
e527440df64c88a9339ab2505bdfeddce6302dbb67aff9fc4fae8e14f259eb29
|
Provenance
The following attestation bundles were made for googleapiutils2-0.20.0-py3-none-any.whl:
Publisher:
publish.yml on mkbabb/googleapiutils2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
googleapiutils2-0.20.0-py3-none-any.whl -
Subject digest:
ecb8fbcf1b018adc6bfb3aa7805e16ddc4a983f95732d22a01a75bdc6c68daa6 - Sigstore transparency entry: 701338904
- Sigstore integration time:
-
Permalink:
mkbabb/googleapiutils2@3f02b24535aff70a3b771b4716a4482f0b4bab6e -
Branch / Tag:
refs/heads/master - Owner: https://github.com/mkbabb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3f02b24535aff70a3b771b4716a4482f0b4bab6e -
Trigger Event:
workflow_dispatch
-
Statement type: