gclientid
Create Google OAuth desktop client IDs locally, without requiring gcloud.
gclientid uses an existing signed-in fastcdp Chrome session. Enable Allow remote debugging in chrome://inspect/#remote-debugging, then create a globally unique project ID, provision its Gmail Desktop OAuth client, and authorize the Gmail account:
from gclientid import authorize_gmail, connect_browser, create_gmail_client, create_project
cdp, page = await connect_browser()
project_id = 'gclientids-your-unique-suffix'
await create_project(page, project_id, name='gclientids')
await create_gmail_client(page, project_id, 'oauth-client.json')
await authorize_gmail(cdp, 'oauth-client.json', 'oauth-token.json')
connect_browser() uses the normal Chrome profile by default. Chrome gives you 60 seconds to approve the debugging connection. The function opens a new tab instead of navigating the currently focused tab. To use the separate CDP Chrome profile on port 9223 instead:
cdp, page = await connect_browser(default_browser=False)
create_gmail_client enables the Gmail API, configures an External OAuth application, adds the full Gmail scope, publishes the unverified application, creates a Desktop client, and writes Google's installed-app client JSON. It selects an email offered by the signed-in Google account for the support and contact fields. It does not require an email or username argument.
On a new Google Auth Platform application, create_gmail_client pauses at Google's API Services terms screen. Complete that visible screen in Chrome and the function continues. Pass accept_terms=True to accept and submit that screen automatically:
await create_gmail_client(page, project_id, 'oauth-client.json', accept_terms=True)
authorize_gmail opens Google's account and consent screens in a new Chrome tab. It selects the account automatically when Google offers one existing account, then approves the requested Gmail access. When Google offers multiple existing accounts, select one by display name or email substring:
await authorize_gmail(cdp, 'oauth-client.json', 'oauth-token.json', account='j@example.com')
The function uses a PKCE loopback flow and writes the access token, refresh token, granted scope, client ID, and creation time to oauth-token.json.
Both JSON files are created with mode 0600. create_gmail_client refuses to overwrite an existing client file because Google only exposes the Desktop client secret at creation time. authorize_gmail replaces the token file when authorization succeeds. Keep both files out of git.
Project deletion is also available. Google keeps a deleted project recoverable for 30 days:
from gclientid import delete_project
await delete_project(page, project_id)
See the privacy policy for how Google user data is handled.
Personal OAuth applications
The intended setup is one Google Cloud project and Desktop OAuth client per developer. Configure its audience as External, publish it In production, and leave it unverified. Google may say that the app "requires verification", but personal-use applications can still authorize up to 100 distinct users. Users see an unverified-app warning during initial authorization; verification is only needed to remove that warning or exceed the lifetime user cap.
Do not leave a continuously running application in Testing. Testing requires an explicit test-user email list, and authorizations requesting Gmail access expire after seven days. An unverified app that is In production needs neither the allowlist nor seven-day reauthorization.
The unrestricted Gmail scope is https://mail.google.com/. It is a restricted
scope and allows reading, composing, sending, and permanently deleting mail.
The application must request this scope during authorization even when it is
already listed on the Google Auth Platform Data Access page.
Google currently requires a Desktop client's client_secret during the token
exchange, including when PKCE is used. The secret is shown only when the client
is created, so capture or download the client JSON immediately. Desktop software
cannot keep this value confidential, but it must still be kept out of git along
with user access and refresh tokens.
Development
pip install -e .[dev]
Versioning
Version lives in gclientid/__init__.py as __version__.
Bump it with:
ship-bump --part 2 # patch
ship-bump --part 1 # minor
ship-bump --part 0 # major
Release
- Ensure your GitHub issues are labeled (
bug,enhancement,breaking). - Run:
ship-release
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 gclientid-0.1.0.tar.gz.
File metadata
- Download URL: gclientid-0.1.0.tar.gz
- Upload date:
- Size: 12.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5741f6eb7bde6ebb066223b7abf4124dc0634f7ac3cb1ed4c4b9197f1d83256b
|
|
| MD5 |
79ac8d98e76c08ef2e5d01ea211f0a4f
|
|
| BLAKE2b-256 |
f8c3c8f14b30ddf5e8e720aabcba2659c096599a20de6dc53009dc5570086cd1
|
File details
Details for the file gclientid-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gclientid-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
418769d09a17e87f07713221f67b70a1c57eeb5da6f8d85b8a36adcc4328d9ae
|
|
| MD5 |
eaf7870a11b4bb8e6302670e9ca26494
|
|
| BLAKE2b-256 |
c3c5bf30a608d97cd5c7b644a3306b0793787c78909dcf67386398a6cbc07a61
|