Created
April 25, 2018 05:48
-
-
Save chulman444/f7ec93da667ff585ef0d8bfccd1d39e0 to your computer and use it in GitHub Desktop.
Google Drive API. Simple Get, Create, List, and get content of file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Refer to https://developers.google.com/api-client-library/python/ | |
from apiclient.discovery import build | |
from httplib2 import Http | |
from oauth2client import file, client, tools | |
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload | |
import mimetypes, io | |
from pprint import pprint | |
class DriveAPI(): | |
def __init__(self): | |
self.service = BuildService.build('drive', 'v3', ['https://www.googleapis.com/auth/drive.file']) | |
# `filename` doesn't have to have extension. However, `name` field in `file_metadata` and `filename` parameter | |
# for `MediaFileUpload` MUST be the same. I thought you could choose the name of the file that you are uploading | |
# | |
# `convert_to` with value 'None' will just 'upload' instead of 'creating a google file type'. For example, use | |
# "application/vnd.google-apps.document" to 'create' a google document. | |
def create(self, filename, mimetype=None, convert_to=None): | |
# Guess mimetype with filename. So, filename with extension doesn't need an explicit mimetype. | |
if mimetype is None: | |
mimetype = mimetypes.guess_type(filename)[0] | |
# mimetype is still `None` if, say, filename has no extension. This will still work but in case of a | |
# text file without extension `.txt`, you are just uploading a file that needs to be downloaded to view. | |
# With the extension however you can view it on Gdrive. | |
file_metadata = { | |
'name': filename, | |
'mimeType': convert_to | |
} | |
media = MediaFileUpload(filename, mimetype=mimetype, resumable=True) | |
request = self.service.files().create(media_body=media, body=file_metadata, fields='id') | |
# Good for confirming and testing what kind of http request is being made. | |
# pprint(request.to_json()) | |
result = request.execute() | |
return result | |
def list(self): | |
request = self.service.files().list() | |
result = request.execute() | |
return result | |
def getMetadata(self, file_id): | |
request = self.service.files().get(fileId=file_id) | |
result = request.execute() | |
return result | |
# Method name could be misleading, but it's like file ... in one aspect that you can | |
# get the content by calling `read` on the result. Hence the `seek(0)` before returning. | |
# | |
# Use `getMetadata` to get the target file's mimetype, and convert to a wanted mimetype | |
# if necessary BEFORE calling this method. For example, if your target file is of google | |
# document type, convert it to `text/plain` and use that mimetype to call this function. | |
# | |
# Refer to [this][1] document for convertible google MIME types and 'normal' MIME types. | |
# | |
# [1]: https://developers.google.com/drive/v3/web/manage-downloads | |
def getFile(self, file_id, mimetype): | |
request = self.service.files().export_media(fileId=file_id, mimeType=mimetype) | |
fh = io.BytesIO() | |
downloader = MediaIoBaseDownload(fh, request) | |
done = False | |
while done is False: | |
status, done = downloader.next_chunk() | |
# print("Download {}.".format(int(status.progress() * 100))) | |
fh.seek(0) | |
return fh | |
class BuildService(): | |
def build(service_name, version, scopes): | |
bs = BuildService(service_name, version, scopes) | |
service = bs.service | |
return service | |
# `scopes` could've been `[]` but took it out so that it throws error if not given. | |
def __init__(self, service_name, version, scopes): | |
self.storage_filepath = 'resources/credentials.json' | |
self.secret_filepath = 'resources/client_secret.json' | |
self.service_name = service_name | |
self.version = version | |
self.scopes = scopes | |
self.service = None | |
SCOPES = self.scopes | |
storage_filepath = self.storage_filepath | |
secret_filepath = self.secret_filepath | |
service_name = self.service_name | |
version = self.version | |
store = file.Storage(storage_filepath) | |
creds = store.get() | |
if not creds or creds.invalid: | |
flow = client.flow_from_clientsecrets(secret_filepath, SCOPES) | |
creds = tools.run_flow(flow, store) | |
self.service = build(service_name, version, http=creds.authorize(Http())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some sample code:
If
a["files"][0]["id"]
is type of google document, it will throw the content of it at your face.