Skip to content

Commit

Permalink
Add back LoadAuth & thread_local HTTP
Browse files Browse the repository at this point in the history
  • Loading branch information
junpeng-jp committed Jul 24, 2022
1 parent 35e9ae3 commit badbd4f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
40 changes: 35 additions & 5 deletions pydrive2/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import json
import google.oauth2.credentials
import google.oauth2.service_account
import threading
from functools import wraps

from googleapiclient.discovery import build
from pydrive2.storage import FileBackend
Expand Down Expand Up @@ -42,6 +44,20 @@ class RefreshError(AuthError):
"""Access token refresh error."""


def LoadAuth(decoratee):
"""Decorator to check if the auth is valid and loads auth if not."""

@wraps(decoratee)
def _decorated(self, *args, **kwargs):
# Initialize auth if needed.
if self.auth is None:
self.auth = GoogleAuth()

return decoratee(self, *args, **kwargs)

return _decorated


class GoogleAuth(ApiAttributeMixin):
"""Wrapper class for oauth2client library in google-api-python-client.
Expand Down Expand Up @@ -78,6 +94,7 @@ def __init__(
"""
self.http_timeout = http_timeout
ApiAttributeMixin.__init__(self)
self.thread_local = threading.local()

if settings is None and settings_file:
try:
Expand All @@ -88,12 +105,12 @@ def __init__(
self.settings = settings or self.DEFAULT_SETTINGS
ValidateSettings(self.settings)

self._storage = None
self._service = None
self._credentials = None
self._client_config = None
self._oauth_type = None
self._flow = None
self._storage = None
self._credentials = None

# Lazy loading, read-only properties
@property
Expand Down Expand Up @@ -153,6 +170,18 @@ def credentials(self):

return self._credentials

@property
def authorized_http(self):
# Ensure that a thread-safe, Authorized HTTP object is provided
# If HTTP object not specified, create or resuse an HTTP
# object from the thread local storage.
if not getattr(self.thread_local, "http", None):
self.thread_local.http = AuthorizedHttp(
self.credentials, http=self._build_http()
)

return self.thread_local.http

# Other properties
@property
def access_token_expired(self):
Expand Down Expand Up @@ -612,9 +641,10 @@ def Authorize(self):
)

def Get_Http_Object(self):
"""Create and authorize an httplib2.Http object. Necessary for
thread-safety.
"""Alias for self.authorized_http. To avoid creating multiple Http Objects by caching it per thread.
:return: The http object to be used in each call.
:rtype: httplib2.Http
"""
return AuthorizedHttp(self.credentials, http=self._build_http())

# updated as alias for
return self.authorized_http
2 changes: 2 additions & 0 deletions pydrive2/drive.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .apiattr import ApiAttributeMixin
from .files import GoogleDriveFile
from .files import GoogleDriveFileList
from .auth import LoadAuth


class GoogleDrive(ApiAttributeMixin):
Expand Down Expand Up @@ -39,6 +40,7 @@ def ListFile(self, param=None):
"""
return GoogleDriveFileList(auth=self.auth, param=param)

@LoadAuth
def GetAbout(self):
"""Return information about the Google Drive of the auth instance.
Expand Down
14 changes: 14 additions & 0 deletions pydrive2/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .apiattr import ApiAttributeMixin
from .apiattr import ApiResource
from .apiattr import ApiResourceList
from .auth import LoadAuth

BLOCK_SIZE = 1024
# Usage: MIME_TYPE_TO_BOM['<Google Drive mime type>']['<download mimetype>'].
Expand Down Expand Up @@ -67,6 +68,7 @@ def __init__(self, auth=None, param=None):
"""Create an instance of GoogleDriveFileList."""
super().__init__(auth=auth, metadata=param)

@LoadAuth
def _GetList(self):
"""Overwritten method which actually makes API call to list files.
Expand Down Expand Up @@ -285,6 +287,7 @@ def GetContentString(
self.FetchContent(mimetype, remove_bom)
return self.content.getvalue().decode(encoding)

@LoadAuth
def GetContentFile(
self,
filename,
Expand Down Expand Up @@ -352,6 +355,7 @@ def download(fd, request):
if bom:
self._RemovePrefix(fd, bom)

@LoadAuth
def GetContentIOBuffer(
self,
mimetype=None,
Expand Down Expand Up @@ -408,6 +412,7 @@ def GetContentIOBuffer(
chunksize=chunksize,
)

@LoadAuth
def FetchMetadata(self, fields=None, fetch_all=False):
"""Download file's metadata from id using Files.get().
Expand Down Expand Up @@ -547,6 +552,7 @@ def InsertPermission(self, new_permission, param=None):

return permission

@LoadAuth
def GetPermissions(self):
"""Get file's or shared drive's permissions.
Expand Down Expand Up @@ -597,6 +603,7 @@ def _WrapRequest(self, request):
request.http = self.auth.Get_Http_Object()
return request

@LoadAuth
def _FilesInsert(self, param=None):
"""Upload a new file using Files.insert().
Expand Down Expand Up @@ -626,6 +633,7 @@ def _FilesInsert(self, param=None):
self.dirty["content"] = False
self.UpdateMetadata(metadata)

@LoadAuth
def _FilesUnTrash(self, param=None):
"""Un-delete (Trash) a file using Files.UnTrash().
:param param: additional parameter to file.
Expand All @@ -650,6 +658,7 @@ def _FilesUnTrash(self, param=None):
self.metadata["labels"]["trashed"] = False
return True

@LoadAuth
def _FilesTrash(self, param=None):
"""Soft-delete (Trash) a file using Files.Trash().
Expand All @@ -675,6 +684,7 @@ def _FilesTrash(self, param=None):
self.metadata["labels"]["trashed"] = True
return True

@LoadAuth
def _FilesDelete(self, param=None):
"""Delete a file using Files.Delete()
(WARNING: deleting permanently deletes the file!)
Expand All @@ -699,6 +709,7 @@ def _FilesDelete(self, param=None):
else:
return True

@LoadAuth
@LoadMetadata
def _FilesUpdate(self, param=None):
"""Update metadata and/or content using Files.Update().
Expand Down Expand Up @@ -730,6 +741,7 @@ def _FilesUpdate(self, param=None):
self.dirty["content"] = False
self.UpdateMetadata(metadata)

@LoadAuth
@LoadMetadata
def _FilesPatch(self, param=None):
"""Update metadata using Files.Patch().
Expand Down Expand Up @@ -770,6 +782,7 @@ def _BuildMediaBody(self):
self.content, self["mimeType"], resumable=True
)

@LoadAuth
def _DownloadFromUrl(self, url):
"""Download file from url using provided credential.
Expand All @@ -784,6 +797,7 @@ def _DownloadFromUrl(self, url):
raise ApiRequestError(errors.HttpError(resp, content, uri=url))
return content

@LoadAuth
def _DeletePermission(self, permission_id):
"""Deletes the permission remotely, and from the file object itself.
Expand Down

0 comments on commit badbd4f

Please sign in to comment.