conduit-py
A unified, opinionated Python client for authenticating and working with Google APIs.
Currently supported:
- Auth: Application Default Credentials (ADC), OAuth client (installed-app flow with token caching), and service account credentials.
- Google Workspace: Sheets (
create_sheet). Docs and Drive scopes are defined but the corresponding services are not yet implemented.
Install
pip install conduit-py
Usage
from conduit_py import Conduit
from conduit_py.google import GoogleScopes
google = Conduit.google(
scopes=[GoogleScopes.SHEETS.WRITE],
oauth_client_path="path/to/client_secret.json",
token_path="path/to/token.json", # optional: cache/reuse the OAuth token
)
sheet = google.workspace.sheets.create_sheet("My Sheet")
print(sheet["spreadsheetId"])
Authentication
Conduit.google(...) picks an authentication strategy based on which arguments you pass, in this
order of precedence:
service_account_path— service account credentials.oauth_client_pathand/ortoken_path— OAuth installed-app flow. Iftoken_pathpoints to an existing, valid cached token, no browser flow is triggered. Iftoken_pathis provided, the token is written there after a successful flow so future runs can skip re-authenticating.- Neither is provided — falls back to Application Default Credentials (ADC).
Note that constructing a client may perform a live network call and, for a fresh OAuth flow, open a browser window for consent.
Errors
All exceptions this package raises inherit from conduit_py.google.exceptions.ConduitGoogleError
and carry a docs_url attribute pointing back to the relevant section below — that same URL is
appended to the exception message, so it's visible directly in tracebacks.
Authentication errors
conduit_py.google.exceptions.GoogleAuthError is raised when authentication fails or is
misconfigured before any API call is made — for example, an OAuth flow with no cached token at
token_path and no oauth_client_path to start a new one from, or a service_account_path /
oauth_client_path that doesn't exist on disk. Check that the path arguments you passed to
Conduit.google(...) point at real files, and that at least one of service_account_path,
token_path, or oauth_client_path is provided (see Authentication above for
precedence).
API errors
conduit_py.google.exceptions.GoogleAPIError wraps a failed Google API request. It carries:
status_code— the HTTP status code from the failed request (e.g.403,404).reason— the reason string from the failed request.
A 403 usually means the authenticated identity lacks permission on the target resource, or the
scopes passed to Conduit.google(...) don't cover the operation being called. A 404 usually
means the resource ID (e.g. spreadsheet_id) doesn't exist or isn't accessible to the
authenticated identity.
Development
uv sync
uv run pytest
Manual smoke test
scripts/manual_smoke_test.py exercises the real Google Sheets API (not part of the automated
suite). It expects an OAuth client secret at credentials.json in the repo root and caches the
resulting token at token.json (both gitignored):
uv run python scripts/manual_smoke_test.py
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 conduit_py-0.1.0.tar.gz.
File metadata
- Download URL: conduit_py-0.1.0.tar.gz
- Upload date:
- Size: 9.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7413663ad1650f4832fb0224631a396869121b953f8637e86b643991b798b389
|
|
| MD5 |
a6957ab580a9b82d18de7fac4d7b6b92
|
|
| BLAKE2b-256 |
38da49082b7b65faf7d8ced571d9edeaa1a146a46e6bb9e6b45245c609d15523
|
Provenance
The following attestation bundles were made for conduit_py-0.1.0.tar.gz:
Publisher:
publish.yml on orilabi-dev/conduit-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
conduit_py-0.1.0.tar.gz -
Subject digest:
7413663ad1650f4832fb0224631a396869121b953f8637e86b643991b798b389 - Sigstore transparency entry: 2269503957
- Sigstore integration time:
-
Permalink:
orilabi-dev/conduit-py@5e80deb3a0625b56a7f002568bdd11d1209a2437 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/orilabi-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5e80deb3a0625b56a7f002568bdd11d1209a2437 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file conduit_py-0.1.0-py3-none-any.whl.
File metadata
- Download URL: conduit_py-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef6e1a435cc6ede7f8e073781f6c8d8b1abfc417df2aba8b113ca05350c4724e
|
|
| MD5 |
7c3f0f0f5158ba31597be408d5d9e6ba
|
|
| BLAKE2b-256 |
62e0c869a4e4b552b496a9eb3ade44a53db0c8355ac7baf79a3a11a0513c71e6
|
Provenance
The following attestation bundles were made for conduit_py-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on orilabi-dev/conduit-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
conduit_py-0.1.0-py3-none-any.whl -
Subject digest:
ef6e1a435cc6ede7f8e073781f6c8d8b1abfc417df2aba8b113ca05350c4724e - Sigstore transparency entry: 2269504246
- Sigstore integration time:
-
Permalink:
orilabi-dev/conduit-py@5e80deb3a0625b56a7f002568bdd11d1209a2437 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/orilabi-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5e80deb3a0625b56a7f002568bdd11d1209a2437 -
Trigger Event:
workflow_dispatch
-
Statement type: