🛼

【Google Drive API】サービスアカウントキーを使用して、共有ドライブにファイルアップロード

2023/10/24に公開

はじめに

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 クライアント ライブラリをインストールします。

requirements.txt
google-auth
google-auth-httplib2
google-auth-oauthlib
google-api-python-client

上記の項目を requirements.txt ファイルに追加しインストールします。

pip install -r requirements.txt

コードの作成

先ほど、ダウンロードしたJSON形式のキーファイルはcredentials.jsonという名前で保存しておきます。

scripts.py
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の取得などでは他にも必要なものがあるかもしれません。ドキュメントを確認して必要なパラメータを追加してください。

参考文献

https://developers.google.com/workspace/guides/create-credentials?hl=ja#choose_the_access_credential_that_is_right_for_you
https://developers.google.com/drive/api/guides/enable-shareddrives?hl=ja

Discussion