Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Asynchronous Features To Close Issue #1637 #2469

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 61 additions & 42 deletions googleapiclient/_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,18 @@

import httplib2

import aiohttp #Team_CKL ADDED CODE
import asyncio #Team_CKL ADDED CODE

try:
import google.auth
import google.auth.credentials
from google.auth.transport.requests import Request as GoogleAuthRequest #Team_CKL ADDED CODE

HAS_GOOGLE_AUTH = True
except ImportError: # pragma: NO COVER
HAS_GOOGLE_AUTH = False

try:
import google_auth_httplib2
except ImportError: # pragma: NO COVER
google_auth_httplib2 = None

try:
import oauth2client
import oauth2client.client
Expand All @@ -38,7 +37,7 @@
HAS_OAUTH2CLIENT = False


def credentials_from_file(filename, scopes=None, quota_project_id=None):
async def credentials_from_file(filename, scopes=None, quota_project_id=None): #Team_CKL MODIFIED
"""Returns credentials loaded from a file."""
if HAS_GOOGLE_AUTH:
credentials, _ = google.auth.load_credentials_from_file(
Expand All @@ -51,7 +50,7 @@ def credentials_from_file(filename, scopes=None, quota_project_id=None):
)


def default_credentials(scopes=None, quota_project_id=None):
async def default_credentials(scopes=None, quota_project_id=None): #Team_CKL MODIFIED
"""Returns Application Default Credentials."""
if HAS_GOOGLE_AUTH:
credentials, _ = google.auth.default(
Expand All @@ -72,7 +71,7 @@ def default_credentials(scopes=None, quota_project_id=None):
)


def with_scopes(credentials, scopes):
async def with_scopes(credentials, scopes): #Team_CKL MODIFIED
"""Scopes the credentials if necessary.

Args:
Expand All @@ -97,7 +96,7 @@ def with_scopes(credentials, scopes):
return credentials


def authorized_http(credentials):
async def authorized_http(credentials): #Team_CKL MODIFIED
"""Returns an http client that is authorized with the given credentials.

Args:
Expand All @@ -106,45 +105,60 @@ def authorized_http(credentials):
oauth2client.client.Credentials]): The credentials to use.

Returns:
Union[httplib2.Http, google_auth_httplib2.AuthorizedHttp]: An
authorized http client.
aiohttp.ClientSession: An authorized aiohttp client session.
"""
from googleapiclient.http import build_http

if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
if google_auth_httplib2 is None:
raise ValueError(
"Credentials from google.auth specified, but "
"google-api-python-client is unable to use these credentials "
"unless google-auth-httplib2 is installed. Please install "
"google-auth-httplib2."
)
return google_auth_httplib2.AuthorizedHttp(credentials, http=build_http())
return aiohttp.ClientSession(auth=GoogleAuthRequest(credentials))
else:
return credentials.authorize(build_http())
headers = await apply_credentials(credentials, {})
return aiohttp.ClientSession(headers=headers)


def refresh_credentials(credentials):
# Refresh must use a new http instance, as the one associated with the
# credentials could be a AuthorizedHttp or an oauth2client-decorated
# Http instance which would cause a weird recursive loop of refreshing
# and likely tear a hole in spacetime.
refresh_http = httplib2.Http()
async def refresh_credentials(credentials): #Team_CKL MODIFIED
"""Refreshes the credentials.

Args:
credentials (Union[
google.auth.credentials.Credentials,
oauth2client.client.Credentials]): The credentials to refresh.
"""
if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
request = google_auth_httplib2.Request(refresh_http)
return credentials.refresh(request)
request = GoogleAuthRequest()
await credentials.refresh(request)
else:
return credentials.refresh(refresh_http)
refresh_http = aiohttp.ClientSession()
await credentials.refresh(refresh_http)
await refresh_http.close()


async def apply_credentials(credentials, headers): #Team_CKL MODIFIED
"""Applies the credentials to the request headers.

Args:
credentials (Union[
google.auth.credentials.Credentials,
oauth2client.client.Credentials]): The credentials to apply.
headers (dict): The request headers.

def apply_credentials(credentials, headers):
# oauth2client and google-auth have the same interface for this.
if not is_valid(credentials):
refresh_credentials(credentials)
Returns:
dict: The updated headers with credentials applied.
"""
if not await is_valid(credentials):
await refresh_credentials(credentials)
return credentials.apply(headers)


def is_valid(credentials):
async def is_valid(credentials): #Team_CKL MODIFIED
"""Checks if the credentials are valid.

Args:
credentials (Union[
google.auth.credentials.Credentials,
oauth2client.client.Credentials]): The credentials to check.

Returns:
bool: True if the credentials are valid, False otherwise.
"""
if HAS_GOOGLE_AUTH and isinstance(credentials, google.auth.credentials.Credentials):
return credentials.valid
else:
Expand All @@ -154,14 +168,19 @@ def is_valid(credentials):
)


def get_credentials_from_http(http):
async def get_credentials_from_http(http): #Team_CKL MODIFIED
"""Gets the credentials from the http client session.

Args:
http (aiohttp.ClientSession): The http client session.

Returns:
google.auth.credentials.Credentials: The credentials.
"""
if http is None:
return None
elif hasattr(http.request, "credentials"):
return http.request.credentials
elif hasattr(http, "credentials") and not isinstance(
http.credentials, httplib2.Credentials
):
elif hasattr(http, "credentials"):
return http.credentials
else:
return None

7 changes: 4 additions & 3 deletions googleapiclient/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
HttpMock,
HttpMockSequence,
HttpRequest,
AsyncHttpRequest, #Team_CKL CODE added
MediaFileUpload,
MediaUpload,
build_http,
Expand Down Expand Up @@ -197,7 +198,7 @@ def build(
discoveryServiceUrl=None,
developerKey=None,
model=None,
requestBuilder=HttpRequest,
requestBuilder=AsyncHttpRequest, #Team_CKL code modified to async
credentials=None,
cache_discovery=True,
cache=None,
Expand Down Expand Up @@ -435,7 +436,7 @@ def _retrieve_discovery_doc(

# Execute this request with retries build into HttpRequest
# Note that it will already raise an error if we don't get a 2xx response
req = HttpRequest(http, HttpRequest.null_postproc, actual_url)
req = AsyncHttpRequest(http, AsyncHttpRequest.null_postproc, actual_url) #Team_CKL Code modified
resp, content = req.execute(num_retries=num_retries)

try:
Expand Down Expand Up @@ -468,7 +469,7 @@ def build_from_document(
http=None,
developerKey=None,
model=None,
requestBuilder=HttpRequest,
requestBuilder=AsyncHttpRequest, #Team_CKL code modified to async
credentials=None,
client_options=None,
adc_cert_path=None,
Expand Down
Loading