Google Cloud Async I/O Authentication Client

raw JSON →
5.4.4 verified Tue May 12 auth: no python install: verified

gcloud-aio-auth is an asyncio-compatible Python client library for Google Cloud Authentication. It provides asynchronous primitives for managing access tokens, IAP tokens, and interacting with IAM. Part of the broader `gcloud-aio` monorepo, it offers async interfaces to various Google Cloud services. The current version is 5.4.4, with releases occurring as part of the actively developed monorepo, often tied to dependency updates or new feature rollouts across components.

pip install gcloud-aio-auth
error Error: The incoming JSON object does not contain a client_email field
cause The provided JSON key file is not a valid Google Cloud service account key, or it's incorrectly formatted, missing required fields like 'client_email' or 'token_uri'. This often occurs when using OAuth 2.0 client IDs instead of service account keys.
fix
Ensure you are using a JSON service account key downloaded from the Google Cloud Console (IAM & Admin -> Service Accounts -> Keys -> Add Key -> Create new key -> JSON), and that this file is correctly passed to gcloud.aio.auth.Token(service_file=...).
error google: could not find default credentials
cause The `gcloud-aio-auth` library, relying on Application Default Credentials (ADC), cannot find valid credentials in the execution environment. This typically means the `GOOGLE_APPLICATION_CREDENTIALS` environment variable is not set, or `gcloud auth application-default login` has not been run or its credentials are not accessible.
fix
Authenticate locally by running gcloud auth application-default login in your terminal, or set the GOOGLE_APPLICATION_CREDENTIALS environment variable to the absolute path of your service account JSON key file (e.g., export GOOGLE_APPLICATION_CREDENTIALS="/path/to/keyfile.json").
error TimeoutError
cause An asynchronous operation, often during token acquisition (e.g., in `acquire_access_token`) or an HTTP request made by the internal `gcloud-aio-auth` session, exceeded its allotted time. This can be due to network latency, slow responses from Google's authentication servers, or an overly aggressive timeout setting.
fix
Increase the timeout parameter when initializing gcloud.aio.auth.Token or when making requests, and consider implementing robust retry logic with exponential backoff for network operations.
error AttributeError: module 'grpc.experimental.aio' has no attribute 'Call'
cause This `AttributeError` often arises from version incompatibilities between `grpcio`, `google-api-core`, and other `google-cloud-python` client libraries, particularly in asynchronous contexts. While not directly from `gcloud-aio-auth`, it indicates a broader dependency conflict within the async Google Cloud ecosystem.
fix
Ensure that google-api-core, grpcio, and all google-cloud-* packages are updated to their latest compatible versions or pinned to known stable versions that work well together (e.g., pip install --upgrade google-api-core grpcio or, if necessary, pin google-api-core==1.17.0 as was a past solution for similar issues).
breaking Python 3.9 support was dropped in gcloud-aio-auth version 5.4.4. Users on Python 3.9 must upgrade their Python version to 3.10 or newer. [cite: auth-5.4.4 release notes]
fix Upgrade Python environment to version 3.10 or later.
gotcha The `auto_decompress` parameter in `aiohttp.ClientSession` could be inadvertently overwritten by `gcloud-aio-auth` in versions prior to 5.4.4. If you explicitly configure `auto_decompress` on your `ClientSession`, ensure you are on version 5.4.4 or later. [cite: auth-5.4.4 release notes, 7]
fix Upgrade to gcloud-aio-auth>=5.4.4. If manually managing `aiohttp.ClientSession`, ensure `auto_decompress=None` is explicitly set on the `Token` (or other gcloud-aio client) constructor if you want to avoid overwriting your session's setting.
gotcha The `gcloud-aio-auth.Token` class manages credentials specifically for the `gcloud-aio` ecosystem. Its default credential discovery relies on the Google Cloud metadata server, which may not be accessible outside of GCP environments (resulting in 'Name does not resolve' errors like 'Cannot connect to host metadata.google.internal'). For such environments, providing credentials explicitly (e.g., via a `service_file`) is necessary. Additionally, direct interoperability by passing `google.auth.default()` credential objects to `gcloud-aio` clients is not the standard pattern and can lead to issues. Always rely on `gcloud-aio.auth.Token` for authentication within `gcloud-aio` clients.
fix Always initialize `gcloud.aio.auth.Token` (or `IapToken`) as described in `gcloud-aio-auth` documentation, letting it handle credential discovery or providing a `service_file` directly. Do not attempt to pass `google.auth.default()` credential objects to `gcloud-aio` client constructors.
gotcha When creating `Token` instances (or any `gcloud-aio` client that manages an internal `aiohttp.ClientSession`), it is crucial to properly close them to prevent resource leaks. Use them within an `async with` statement or explicitly call `await token.close()` when done.
fix Ensure `Token` instances are closed. The recommended pattern is `async with Token(...) as token:` or, if not using a context manager, explicitly call `await token.close()` before your application exits.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.60s 60.0M
3.10 alpine (musl) - - 0.62s 59.3M
3.10 slim (glibc) wheel 6.3s 0.40s 62M
3.10 slim (glibc) - - 0.43s 61M
3.11 alpine (musl) wheel - 0.71s 68.2M
3.11 alpine (musl) - - 0.90s 67.5M
3.11 slim (glibc) wheel 5.5s 0.64s 70M
3.11 slim (glibc) - - 0.60s 70M
3.12 alpine (musl) wheel - 0.87s 62.7M
3.12 alpine (musl) - - 0.93s 62.0M
3.12 slim (glibc) wheel 4.6s 0.87s 65M
3.12 slim (glibc) - - 0.95s 64M
3.13 alpine (musl) wheel - 0.90s 62.1M
3.13 alpine (musl) - - 0.96s 61.3M
3.13 slim (glibc) wheel 4.8s 0.83s 64M
3.13 slim (glibc) - - 0.97s 64M
3.9 alpine (musl) wheel - 0.56s 45.5M
3.9 alpine (musl) - - 0.58s 45.5M
3.9 slim (glibc) wheel 6.9s 0.52s 48M
3.9 slim (glibc) - - 0.49s 48M

This quickstart demonstrates how to initialize the `Token` class, which handles credential discovery (via `GOOGLE_APPLICATION_CREDENTIALS` or Application Default Credentials) and automatic token refreshing. It then shows how to use the obtained access token to make an authenticated request using `aiohttp.ClientSession` to a Google Cloud API. Remember to run `gcloud auth application-default login` for local development or set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable.

import asyncio
import os
import aiohttp
from gcloud.aio.auth import Token

async def main():
    # Attempt to use GOOGLE_APPLICATION_CREDENTIALS environment variable or ADC
    # For local development, ensure `gcloud auth application-default login` has been run
    # or GOOGLE_APPLICATION_CREDENTIALS points to a service account key file.
    service_account_path = os.environ.get('GOOGLE_APPLICATION_CREDENTIALS', '')
    
    print("Initializing Token...")
    # Initialize Token; it will try to discover credentials if service_file is None.
    # Specify necessary scopes for your application.
    token = Token(
        service_file=service_account_path if service_account_path else None,
        scopes=["https://www.googleapis.com/auth/cloud-platform"]
    )
    
    async with aiohttp.ClientSession() as session:
        try:
            # Get an access token (automatically refreshed by the Token instance)
            access_token = await token.get()
            print(f"Successfully obtained access token (first 10 chars): {access_token[:10]}...")
            
            # Example: Make an authenticated request to a Google Cloud API
            # (e.g., list buckets in Google Cloud Storage)
            headers = {"Authorization": f"Bearer {access_token}"}
            print("Making a dummy authenticated request to Google Cloud Storage API...")
            async with session.get(
                "https://www.googleapis.com/storage/v1/projects/_/buckets",
                headers=headers
            ) as response:
                if response.status == 200:
                    print(f"Request to GCS successful (status 200). Some buckets (if any): {await response.json()}")
                else:
                    print(f"Request failed with status: {response.status}")
                    print(f"Response body: {await response.text()}")
                    
        except Exception as e:
            print(f"An error occurred: {e}")
        finally:
            # Ensure the token's internal session is closed
            await token.close()

if __name__ == "__main__":
    asyncio.run(main())