【Google Drive API】サービスアカウントキーを使用して、共有ドライブにファイルアップロード
はじめに
Google Drive APIを利用してcsvファイルをアップロードする機能を作成しました。本記事ではその手順をまとめます。
APIの有効化
プロジェクトを作成し、Google Cloud コンソールから、Google Drive API を有効にしておきます。
資格情報の選択
リクエストを送る際の認証方法を選択します。認証方法には、下の3つがあります。
資格情報の種類 | 説明 |
---|---|
APIキー | 一般公開データに匿名でアクセスを提供し、認証不要 |
OAuth クライアント ID | リクエストを送信する際にブラウザを開いてユーザー認証 |
サービスアカウント | 認証情報をJSON形式で保管し、リクエストを送信する際に認証 |
今回は、公開データではないためAPIキー
は使用できません。
また、Dockerを使用しているためコンテナ内でブラウザを直接開くことできずOAuth クライアント ID
も使用できませんでした。
以上の理由から、サービスアカウント
を使用して実装を進めていきます。
サービスアカウントキーを取得する
サービスアカウントによる認証方法では、サービスアカウントキーというJSON形式のキーファイルを使用します。
サービスアカウントの編集画面からキー
タブを選択し、鍵の追加
からJSON形式のキーを作成します。
作成したファイルはダウンロードしておきます。
クライアントライブラリのインストール
PythonでGoogle Drive APIを操作するために、Google API クライアント ライブラリをインストールします。
google-auth
google-auth-httplib2
google-auth-oauthlib
google-api-python-client
上記の項目を requirements.txt ファイルに追加しインストールします。
pip install -r requirements.txt
コードの作成
先ほど、ダウンロードしたJSON形式のキーファイルはcredentials.json
という名前で保存しておきます。
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
# 認証情報を読み込む
creds = service_account.Credentials.from_service_account_file(
'credentials.json', # JSON形式のキーファイルへのパス
scopes=['https://www.googleapis.com/auth/drive']
)
# Google Drive APIクライアントを作成
drive_service = build('drive', 'v3', credentials=creds)
# アップロードするファイルの情報
file_name = 'example.csv'
file_metadata = {
'name': file_name,
'parents': ['1c2sj5hl...'], # ファイルID(ドライブURIの’folders/’に続く値)
}
# ファイルをアップロード
media = MediaFileUpload(file_name, mimetype='application/csv')
file = drive_service.files().create(
body=file_metadata,
media_body=media,
fields='id',
supportsAllDrives=True # ポイント!
).execute()
print(f'File ID: {file.get("id")}')
supportsAllDrives=True
を追加する
共有ドライブの時はコードブロック内のポイント!
の箇所にsupportsAllDrives=True
を記述することを忘れないようにします。
この記述を忘れると、下のようなFile not found
エラーが発生してしまいます。
File "...", line 100, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 404 when requesting https://www.googleapis.com/upload/drive/v3/files?fields=id&alt=json&uploadType=multipart returned "File not found: xxx.". Details: "[{'message': 'File not found: xxx.', 'domain': 'global', 'reason': 'notFound', 'location': 'fileId', 'locationType': 'parameter'}]">
アップロードはsupportsAllDrives=True
のみの追加で良いですが、listの取得などでは他にも必要なものがあるかもしれません。ドキュメントを確認して必要なパラメータを追加してください。
参考文献
Discussion