本記事では、PythonでGoogle Drive APIを使用して、Google Driveに画像をアップロードする方法を以下の2パターン紹介します。
- 画像ファイル(jpg, png等)をアップロードする場合
- バイナリデータをアップロードする場合
バイナリデータをアップロードするケースとしては、HTTP通信経由で取得した画像(例えばWebスクレイピング等)をファイル保存せず、そのままアップロードしたい等が挙げられます。
以前作成した名刺管理アプリでもこの技術を使用しているので、興味のある方は見てみてください。

準備
PythonでGoogle Drive APIを使用するには、Python用Google Client APIをインストールしておく必要があります。
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib画像ファイルをアップロードする方法
Google Drive API経由で、Google Driveに画像ファイル(jpg, png等)をアップロードする方法は公式ガイドに記載があります。
以下公式のサンプルを貼りますが、MediaFileUploadメソッドを使用すればOKです。
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from googleapiclient.http import MediaFileUpload
def upload_basic():
"""Insert new file.
Returns : Id's of the file uploaded
Load pre-authorized user credentials from the environment.
TODO(developer) - See https://developers.google.com/identity
for guides on implementing OAuth2 for the application.
"""
creds, _ = google.auth.default()
try:
# create drive api client
service = build("drive", "v3", credentials=creds)
file_metadata = {"name": "download.jpeg"}
media = MediaFileUpload("download.jpeg", mimetype="image/jpeg")
# pylint: disable=maybe-no-member
file = (
service.files()
.create(body=file_metadata, media_body=media, fields="id")
.execute()
)
print(f'File ID: {file.get("id")}')
except HttpError as error:
print(f"An error occurred: {error}")
file = None
return file.get("id")
if __name__ == "__main__":
upload_basic()“file_metadata”でGoogle Drive上でのファイル名等のメタデータを記述、”media”にアップロード対象ファイルを指定しています。
file.service.files().create(body, media_body, fields).execute()でアップロードが実行されます。
画像のバイナリデータをアップロードする方法
バイナリデータをアップロードする方法は公式ガイドには記載がありません。
Github上のソースで言及されています。

MediaIoBaseUploadを使用すればOKです。
ただし、以下に示すように、アップロード対象データをBytesIO型にする必要があります。
※上図赤線部分をクリックして出てくる詳細情報に記載があります。

以下実装例です。
import io
import google.auth
from googleapiclient.discovery import build
def upload_binary(image):
#image: バイナリデータ
creds, _ = google.auth.default()
image_byio = io.BytesIO(image)
try:
service = build("drive", "v3", credentials=creds)
file_metadata = {"name": "download.jpeg"}
media = MediaIoBaseUpload(image_byio, mimetype="image/jpeg")
file = (
service.files()
.create(body=file_metadata, media_body=media, fields="id")
.execute()
)
return file.get("id")io.BytesIOで画像データをBytesIO型に変換し、MediaIoBaseUploadメソッドに入力しています。
その他の流れはファイルアップロード時と同様です。
さいごに
- 画像ファイル(jpg, png等)をアップロードする場合:MediaFileUpload
- バイナリデータをアップロードする場合:MediaIoBaseUpload
コメント