{"id":40562750,"url":"https://github.com/mkbabb/googleapiutils2","last_synced_at":"2026-01-21T01:03:59.046Z","repository":{"id":145568663,"uuid":"522705510","full_name":"mkbabb/googleapiutils2","owner":"mkbabb","description":"Wrapper for Google's Python API","archived":false,"fork":false,"pushed_at":"2025-11-14T18:25:41.000Z","size":1448,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-11-14T20:35:11.677Z","etag":null,"topics":["google","google-api","google-drive-api","google-sheets-api"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mkbabb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-08-08T20:59:20.000Z","updated_at":"2025-11-14T18:22:47.000Z","dependencies_parsed_at":"2023-05-25T23:30:42.911Z","dependency_job_id":"76e2722f-b8c0-4356-976c-1532c0643c99","html_url":"https://github.com/mkbabb/googleapiutils2","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/mkbabb/googleapiutils2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkbabb%2Fgoogleapiutils2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkbabb%2Fgoogleapiutils2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkbabb%2Fgoogleapiutils2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkbabb%2Fgoogleapiutils2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mkbabb","download_url":"https://codeload.github.com/mkbabb/googleapiutils2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkbabb%2Fgoogleapiutils2/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28620573,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T23:49:58.628Z","status":"ssl_error","status_checked_at":"2026-01-20T23:47:29.996Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google","google-api","google-drive-api","google-sheets-api"],"created_at":"2026-01-21T01:03:58.247Z","updated_at":"2026-01-21T01:03:59.040Z","avatar_url":"https://github.com/mkbabb.png","language":"Python","readme":"# googleapiutils2\n\nPython wrapper for Google APIs: Drive, Sheets, Gmail, Admin, Groups, Geocoding.\n\n## Installation\n\n### via pip\n```bash\npip install googleapiutils2\n```\n\n### via uv\n```bash\nuv add googleapiutils2\n```\n\nRequires Python ^3.12\n\n## Overview\n\ngoogleapiutils2 provides a unified, Pythonic interface for Google APIs with built-in:\n- **Automatic retry** - 10 retries with exponential backoff\n- **TTL caching** - 80s cache on frequently accessed data\n- **Request throttling** - Rate limiting to prevent quota exhaustion\n- **Type hints** - Full IDE support via google-api-stubs\n- **URL support** - Accept file/sheet IDs or URLs interchangeably\n\n## Quick Start\n\n### Drive\n```python\nfrom googleapiutils2 import Drive, GoogleMimeTypes\n\ndrive = Drive()\n\n# Upload\ndrive.upload(\"file.csv\", to_mime_type=GoogleMimeTypes.sheets, parents=[\"folder_id\"])\ndrive.upload(\"./folder\", recursive=True, update=True)\n\n# List\nfor file in drive.list(query=\"name contains 'report'\"):\n    print(f\"{file['name']}: {file['id']}\")\n\n# Download\ndrive.download(\"file_id\", \"./output.pdf\", mime_type=GoogleMimeTypes.pdf)\ndrive.download(\"folder_id\", \"./local_folder\", recursive=True)\n```\n\n### Sheets\n```python\nfrom googleapiutils2 import Sheets, SheetsValueRange\n\nsheets = Sheets()\nSheet1 = SheetsValueRange(sheets, sheet_url, \"Sheet1\")\n\n# Slice notation (NumPy-like)\nSheet1[1, \"A\"].update([[\"Value\"]])\nSheet1[2:5, 1:3].update([[1,2,3], [4,5,6], [7,8,9]])\ndata = Sheet1[...].read()\n\n# Batch updates\nsheets.batch_update(sheet_url, {\n    Sheet1[1, ...]: [[\"Header 1\", \"Header 2\"]],\n    Sheet1[2:4, ...]: [[1, 2], [3, 4]]\n})\n\n# DataFrame integration\nimport pandas as pd\ndf = Sheet1[...].to_frame()\nSheet1.update(sheets.from_frame(df, include_header=True))\n\n# Formatting\nsheets.format(sheet_url, Sheet1[1, ...], bold=True, background_color=\"#d48686\")\n```\n\n### Mail\n```python\nfrom googleapiutils2 import Mail\n\nmail = Mail()\n\n# Send email\nmail.send(\n    sender=\"me@example.com\",\n    to=\"user@example.com\",\n    subject=\"Test\",\n    body=\"Hello\"\n)\n\n# List messages\nfor msg in mail.list_messages(query=\"from:user@example.com after:2024/01/01\"):\n    print(msg['id'], msg['snippet'])\n```\n\n### Admin (Workspace)\n```python\nfrom googleapiutils2 import Admin\n\nadmin = Admin()\n\n# Create user\nuser = admin.create_user(\n    primary_email=\"test@domain.com\",\n    given_name=\"Test\",\n    family_name=\"User\",\n    password=\"temp123\"\n)\n\n# List users\nfor user in admin.list_users(query=\"givenName:John\"):\n    print(user['primaryEmail'])\n```\n\n### Groups\n```python\nfrom googleapiutils2 import Groups\n\ngroups = Groups()\n\n# Create group\ngroup = groups.create(\n    email=\"team@domain.com\",\n    name=\"Engineering\",\n    description=\"All engineers\"\n)\n\n# Add members\ngroups.members_insert(\"team@domain.com\", \"user@domain.com\")\nfor member in groups.members_list(\"team@domain.com\"):\n    print(member['email'], member['role'])\n```\n\n### Geocode\n```python\nfrom googleapiutils2 import Geocode\n\ngeocoder = Geocode(api_key=\"YOUR_API_KEY\")\n\n# Address to coordinates\nresults = geocoder.geocode(\"1600 Amphitheatre Parkway, Mountain View, CA\")\nprint(results[0]['geometry']['location'])  # {'lat': 37.422, 'lng': -122.084}\n\n# Coordinates to address\nresults = geocoder.reverse_geocode(lat=37.422, long=-122.084)\n```\n\n### Monitor (Change Detection)\n```python\nfrom googleapiutils2 import SheetsMonitor\n\ndef on_change(data, monitor):\n    print(f\"Sheet updated: {len(data)} rows\")\n\nmonitor = SheetsMonitor(sheets, drive, sheet_url, on_change, interval=30)\nmonitor.start()\n```\n\n## Authentication\n\nTwo authentication methods supported:\n\n### Service Account (Recommended for automation)\n\n**When to use:**\n- Automated scripts and server applications\n- No user interaction needed\n- Domain-wide delegation (Workspace only)\n\n**Setup:**\n1. Enable APIs: https://console.cloud.google.com/apis/library\n2. Create Service Account: https://console.cloud.google.com/iam-admin/serviceaccounts\n3. Download JSON key file\n\n**Usage:**\n```python\nfrom googleapiutils2 import Drive, get_oauth2_creds\n\n# Basic service account\ncreds = get_oauth2_creds(client_config=\"auth/service-account.json\")\ndrive = Drive(creds=creds)\n\n# With domain-wide delegation (Workspace only)\ncreds = get_oauth2_creds(client_config=\"auth/service-account.json\")\ncreds = creds.with_subject(\"user@domain.com\")  # Impersonate user\ndrive = Drive(creds=creds)\n```\n\n### OAuth2 Client (For user authorization)\n\n**When to use:**\n- Desktop applications\n- User consent required\n- Personal Google accounts\n\n**Setup:**\n1. Enable APIs: https://console.cloud.google.com/apis/library\n2. Create OAuth Client: https://console.cloud.google.com/apis/credentials/oauthclient (Desktop app)\n3. Configure consent screen: https://console.cloud.google.com/apis/credentials/consent\n\n**Usage:**\n```python\n# First run: opens browser for authorization\n# Token saved to auth/token.pickle for reuse\ncreds = get_oauth2_creds(\n    client_config=\"auth/oauth2_credentials.json\",\n    token_path=\"auth/token.pickle\"\n)\ndrive = Drive(creds=creds)\n```\n\n### Auto-discovery\n\n```python\n# Auto-discovery checks ./auth/credentials.json or GOOGLE_API_CREDENTIALS env var\ndrive = Drive()\nsheets = Sheets()\n```\n\n## Features\n\n### Drive\n\n**Upload:**\n- Files, folders (recursive)\n- DataFrames to Google Sheets\n- Markdown ↔ Google Docs conversion\n- MD5 checksum for skip-if-unchanged\n\n**Download:**\n- Files, folders (recursive)\n- Format conversion (Sheets → xlsx, Docs → docx, etc.)\n- Chunked downloads for large files\n\n**Operations:**\n- `get`, `list`, `create`, `copy`, `update`, `delete`\n- `sync` - Sync local ↔ remote directories\n- `empty_trash` - Empty trash\n- Permissions management\n\n### Sheets\n\n**Slice Notation:**\n```python\nSheet[1, \"A\"]           # Single cell\nSheet[2:5, 1:3]         # Range\nSheet[1, ...]           # Entire row\nSheet[..., \"A\"]         # Entire column\nSheet[-1, -1]           # Last cell\nSheet[\"A1:B2\"]          # A1 notation\n```\n\n**Operations:**\n- CRUD: create, read, update, delete, append, clear\n- Formatting: bold, colors, alignment, wrap, freeze\n- Batch updates with auto-chunking\n- Column alignment for dict data\n- Auto-resize on overflow\n\n**DataFrame Integration:**\n```python\ndf = Sheet1[...].to_frame()\nSheet1.update(sheets.from_frame(df, include_header=True))\n```\n\n### Mail\n\n**Messages:**\n- Send (plain text, HTML)\n- Create drafts\n- List, get, modify, trash, delete\n\n**Labels:**\n- List, create, delete, modify\n- Apply/remove labels from messages\n\n### Admin (Workspace)\n\n**User Management:**\n- Create, update, delete users\n- Suspend/unsuspend accounts\n- Password management\n- Admin role management\n- Search by name, email, org unit\n\n### Groups\n\n**Group Operations:**\n- Create, update, delete groups\n- List groups by domain/customer/user\n\n**Member Operations:**\n- Add, remove, update members\n- List members\n- Check membership\n- Role management (OWNER, MANAGER, MEMBER)\n\n### Geocode\n\n**Operations:**\n- Forward geocoding (address → coordinates)\n- Reverse geocoding (coordinates → address)\n- Address component parsing\n- Location type (ROOFTOP, RANGE_INTERPOLATED, etc.)\n\n## Architecture\n\n**Base Class:** `DriveBase` - All API classes inherit (except Geocode)\n- TTL caching (80s, 128 entries)\n- Retry decorator (10 retries, 30s delay, exponential backoff)\n- Throttling (0.1s individual, 1s batch)\n- Background request queueing\n\n**Exception Hierarchy:**\n```python\nGoogleAPIException\n├── InvalidRequestError\n├── OverQueryLimitError\n├── RequestDeniedError\n├── NotFoundError\n└── UnknownError\n```\n\n**Key Patterns:**\n- TYPE_CHECKING blocks for circular import prevention\n- Generator pattern for pagination\n- MIME type auto-detection and conversion\n- MD5 checksum caching\n- Slice notation for Sheets (NumPy-like)\n\n## File Structure\n\n```\ngoogleapiutils2/\n├── utils/           # Core: DriveBase, auth, caching, retry, MIME types\n├── drive/           # Google Drive API\n├── sheets/          # Google Sheets API\n├── mail/            # Gmail API\n├── admin/           # Workspace Admin API\n├── groups/          # Google Groups API\n├── geocode/         # Maps Geocoding API\n└── monitor.py       # Change detection (DriveMonitor, SheetsMonitor)\n```\n\n## Dependencies\n\n- google-api-python-client ^2.168.0\n- google-auth ^2.39.0\n- google-auth-oauthlib ^1.2.1\n- pandas ^2.2.3\n- cachetools ^5.5.2\n- loguru ^0.7.3\n- requests ^2.32.3\n\n## Testing\n\n```bash\npytest test/\n```\n\nTests use real Google APIs with session-scoped fixtures and automatic cleanup.\n\n## Documentation\n\n- **Project Overview:** [CLAUDE.md](CLAUDE.md)\n- **Utils Module:** [googleapiutils2/utils/CLAUDE.md](googleapiutils2/utils/CLAUDE.md)\n- **Drive Module:** [googleapiutils2/drive/CLAUDE.md](googleapiutils2/drive/CLAUDE.md)\n- **Sheets Module:** [googleapiutils2/sheets/CLAUDE.md](googleapiutils2/sheets/CLAUDE.md)\n- **Mail Module:** [googleapiutils2/mail/CLAUDE.md](googleapiutils2/mail/CLAUDE.md)\n- **Admin Module:** [googleapiutils2/admin/CLAUDE.md](googleapiutils2/admin/CLAUDE.md)\n- **Groups Module:** [googleapiutils2/groups/CLAUDE.md](googleapiutils2/groups/CLAUDE.md)\n- **Geocode Module:** [googleapiutils2/geocode/CLAUDE.md](googleapiutils2/geocode/CLAUDE.md)\n\n## Examples\n\nSee [examples/](examples/) for more usage patterns:\n- `drive_upload.py` - File/folder uploads\n- `sheets_crud.py` - Sheet operations and formatting\n- `mail.py` - Email sending\n- `monitor.py` - Change detection\n- And more...\n\n## License\n\nMIT\n\n## Repository\n\nhttps://github.com/mkbabb/googleapiutils2\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkbabb%2Fgoogleapiutils2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmkbabb%2Fgoogleapiutils2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkbabb%2Fgoogleapiutils2/lists"}