aiogoogle
repository·master·Indexed 42 days ago
https://github.com/omarryhan/aiogoogleAn asynchronous Python client for non-blocking access to Google's public APIs, including Gmail, Drive, Calendar, Sheets, Docs, Maps, YouTube, and Translate. It provides a Pythonic wrapper for the Google Discovery Service, supporting multiple authentication methods such as OAuth2, OpenID Connect, Service Accounts, and API keys.
What's inside aiogoogle
- Aiogoogle is an asynchronous Python client for accessing Google's public APIs. It provides async support for a wide range of services, allowing developers to integrate Google features into asynchronous applications without blocking the event loop. Supported APIs include Google Calendar, Drive, Gmail, Sheets, Docs, Maps, YouTube, Translate, and many others.
How the Discovery Service and API structure works
masterAiogoogle is a Pythonic wrapper for Google's Discovery Service. Instead of hardcoding every API, it downloads machine-readable specifications (discovery documents) to build an API object dynamically.
API Hierarchy
- Resources: Represent entities (e.g.,
videos,url). Resources can be nested (e.g.,youtube_v3.videos.comments). - Methods: The actual actions you can perform on a resource (e.g.,
list,get,insert).
Crucial Rule: You cannot call a resource directly to get data; you must call a method associated with that resource.
- Resources: Represent entities (e.g.,
Handle API Pagination with `full_res=True`
masterWhen an API response contains multiple pages of data, you can use the
full_res=Trueargument in.as_user()(or.as_api_key()). This returns an asynchronous iterator that allows you to loop through all pages of results.Instead of a single dictionary, the returned object is an
AsyncIterableof pages.async def list_files(): async with Aiogoogle(user_creds=user_creds) as aiogoogle: drive_v3 = await aiogoogle.discover('drive', 'v3') # full_res=True enables pagination full_res = await aiogoogle.as_user( drive_v3.files.list(), full_res=True ) # Iterate through each page asynchronously async for page in full_res: for file in page['files']: print(file['name']) asyncio.run(list_files())Browse Google Discovery Documents Manually
masterBefore writing code, you can manually inspect the structure of a Google API by accessing its discovery document. This helps you identify resources, methods, and required parameters.
- Use the following URL pattern in your browser:
https://www.googleapis.com/discovery/v1/apis/{api}/{version}/restExample for YouTube v3:https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest - Use a JSON viewer extension to navigate the structure.
- Follow the hierarchy:
resources$\rightarrow$[resource_name]$\rightarrow$methods$\rightarrow$[method_name]$\rightarrow$parametersto understand how to construct youraiogooglecalls.
- Use the following URL pattern in your browser:
Integrate OpenID Connect for user authentication
masterUse OpenID Connect (OIDC) if you need to identify the user (e.g., for 'Social Sign-in'). OIDC is a superset of OAuth2; it provides the same access tokens but also returns an ID token containing user 'claims' (like
sub,email, etc.).1. Generate Authorization URL
Use
aiogoogle.openid_connect.authorization_url. You should provide anonceto prevent replay attacks.2. Handle the Callback
Exchange the grant code for
UserCredsand then useaiogoogle.openid_connect.get_user_infoto retrieve the user's identity claims.Note: Use the
subclaim to uniquely identify users. Do not rely onemailfor unique identification, as emails can change.# 1. Generate URL with nonce uri = aiogoogle.openid_connect.authorization_url( client_creds={ 'client_id': '...', 'client_secret': '...', 'redirect_uri': '...', 'scopes': ['...'] }, nonce='random_nonce_value' ) # 2. Handle callback full_user_creds = await aiogoogle.openid_connect.build_user_creds( grant=request.args.get('code'), client_creds=CLIENT_CREDS, nonce='random_nonce_value', verify=False ) # 3. Get user identity claims full_user_info = await aiogoogle.openid_connect.get_user_info(full_user_creds) # full_user_info contains claims like 'sub', 'email', etc.Authenticate using GOOGLE_APPLICATION_CREDENTIALS environment variable
masterYou can point the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable to your JSON key file location. To makeAiogoogleload these credentials, you must callawait aiogoogle.service_account_manager.detect_default_creds_source()before making API calls.export GOOGLE_APPLICATION_CREDENTIALS="location_of_key_file.json"import asyncio from aiogoogle import Aiogoogle from aiogoogle.auth.creds import ServiceAccountCreds creds = ServiceAccountCreds(scopes=["https://www.googleapis.com/auth/cloud-platform"]) async def list_storage_buckets(project_id=creds["project_id"]): aiogoogle = Aiogoogle(service_account_creds=creds) # Load the service account key from the environment variable await aiogoogle.service_account_manager.detect_default_creds_source() async with aiogoogle: storage = await aiogoogle.discover("storage", "v1") res = await aiogoogle.as_service_account( storage.buckets.list(project=creds["project_id"]) ) print(res) if __name__ == "__main__": asyncio.run(list_storage_buckets())Authenticate using an API Key for public data
masterFor accessing public data where no user authorization is required, you can use a simple API key. Pass the
api_keystring to theAiogoogleconstructor and useaiogoogle.as_api_key()to execute calls.async with Aiogoogle(api_key='YOUR_API_KEY') as aiogoogle: google_api = await aiogoogle.discover('google_api', 'v1') result = await aiogoogle.as_api_key( google_api.foo.bar(baz='foo') )Set up Google Cloud project and credentials
masterBefore using
aiogoogle, you must configure your environment in the Google Cloud Console:- Create a project: Use the Google APIs and Services dashboard.
- Enable an API: Select the specific API you need (e.g., Gmail, Drive, Calendar) in the API Library.
- Create credentials: Use the Credentials wizard to generate your
client_idandclient_secret. - Explore APIs: Use Google's APIs Explorer to find the specific methods you need.
Authenticate using a Service Account key file
masterYou can authenticate using a user-managed service account JSON key file by passing its contents to
ServiceAccountCreds. This is useful for applications that need to perform actions on their own. When using this method, useaiogoogle.as_service_account()to execute the discovered API calls.import json import asyncio from aiogoogle import Aiogoogle from aiogoogle.auth.creds import ServiceAccountCreds # Load the JSON key file service_account_key = json.load(open('test_service_account.json')) # Initialize credentials with required scopes creds = ServiceAccountCreds( scopes=[ "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write", ], **service_account_key ) async def list_storage_buckets(project_id=creds["project_id"]): async with Aiogoogle(service_account_creds=creds) as aiogoogle: storage = await aiogoogle.discover("storage", "v1") # Use as_service_account to wrap the API call res = await aiogoogle.as_service_account( storage.buckets.list(project=creds["project_id"]) ) print(res) if __name__ == "__main__": asyncio.run(list_storage_buckets())Programmatically browse and inspect an API
masterOnce you have discovered an API using
await aiogoogle.discover(name, version), you can inspect its structure programmatically:- List Resources: Access
api_object['resources']. - Access a Resource: Use dot notation (e.g.,
api_object.resource_name). - Check Available Methods: Use
resource.methods_available. - Inspect a Method: Access the method object (e.g.,
resource.method_name) to see:description: A string describing the method.optional_parameters: A list of parameter names.required_parameters: A list of parameter names.parameters: A dictionary containing detailed metadata (type, description, location) for each parameter.
# Example: Inspecting a method url_resource = url_shortener.url print(url_resource.methods_available) # ['get', 'insert', 'list'] list_url = url_resource.list print(list_url.optional_parameters) # ['projection', 'start_token', ...] print(list_url.parameters['start_token'])- List Resources: Access
Install aiogoogle via pip
masterTo use the asynchronous Google API client, install the package using pip.
$ pip install aiogoogleDownload and Upload files to Google Drive
masterUse the Google Drive API via
aiogoogleto manage files.- To download: Use
files.get()withdownload_file=pathandalt='media'inside an.as_user()call. - To upload: Use
files.create()with theupload_file=pathparameter. - To upload via stream: Use
files.create()with thepipe_from=iterableparameter, whereiterableis anAsyncIterableyielding chunks.
# Download await aiogoogle.as_user( drive_v3.files.get(fileId=file_id, download_file=path, alt='media'), ) # Upload file await aiogoogle.as_user( drive_v3.files.create(upload_file=path) ) # Upload via AsyncIterable async def yield_file(): yield b'chunk1' yield b'chunk2' await aiogoogle.as_user( drive_v3.files.create(pipe_from=yield_file()) )- To download: Use