💡

PythonでGoogle Drive APIを使う

2023/10/20に公開

PythonでGoogle Drive APIを使ってGoogle Driveにアクセスすることをしてみたので、その手順をつらつらと書いてみます。
また、基本的には公式ガイド通りなので何か困ったことがありましたら、こちらを確認してもらえたら情報は正確かと思います。
https://developers.google.com/drive/api/quickstart/python?hl=ja

この記事の想定読者

  • PythonでGoogle Drive APIを使ってGoogle Driveの操作をしたいけど、何をどうすれば良いのかわからない方

Google Cloud

Google Drive API の有効化

  1. PythonからAPIを使ってアクセスしたいGoogleDriveのGoogleアカウントでGoogleCloudにアクセスします。

  2. 上部メニューから "コンソール" のボタンを押して、コンソールにアクセスします。

  3. プロジェクトの選択ボタンを押して、新規プロジェクトを作成します。

  4. 任意のプロジェクト名を入力したあとで、IDを確認します。
    もし自動生成されたIDが気に食わないようでしたら、文字リンクになっている"編集"を押してIDを修正し "作成" を押します。

  5. 左上部のメニューから、"APIとサービス" -> "有効なAPIとサービス" を選択します。

  6. "APIとサービスの有効化" を押します。

  7. APIライブラリが開くので、検索バーで "google drive api" と入力し検索します。

  8. 検索結果からGoogle Drive APIを選択して、"有効にする" を押します。

認証情報の作成

  1. メニューから "認証情報" -> "認証情報を作成" -> "OAuthクライアントID" を選択します。

  2. アプリケーションの種類にて "デスクトップアプリ" を選択して任意の名前を入力後、"作成" を押します。

  3. ポップアップ画面で認証情報が表示されるので、"jsonをダウンロード" を押します。jsonファイルをダウンロードする前にポップアップ画面を閉じてしまった場合は管理画面上からもjsonファイルをダウンロードできます。

  4. ダウンロードしたjsonファイルのファイル名をcredentials.json に変更します。

OAuth同意画面の設定

  1. メニューから "OAuth同意画面" を選択、UserTypeで "外部" を選択したら、"作成" を押します。

  2. [OAuth同意画面]
    以下の欄を入力後、"保存して次へ" を押します。

    • アプリ情報
      • アプリ名:任意のアプリ名
      • ユーザーサポートメール:利用可能なメールアドレス
    • デベロッパーの連絡先情報:利用可能なメールアドレス

  3. [スコープ]

    • "スコープを追加または削除" を選択します。
    • フィルタに "Google Drive API" と入力しAPIで操作したいスコープを選択(ここでは全ての操作が可能なスコープを選択)したあと、"更新" を押します。
    • "保存して次へ" を押します。
  4. [テストユーザー]
    "+ADD USERS" を押して自分のGoogleアカウント(Gmailアドレス)を追加したあと、"保存して次へ" を押します。

  5. [概要]
    ページの一番最下部にある "ダッシュボードに戻る" を押します。

認証

  1. pipのパッケージをインストールします。

    pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
    
  2. ここからquickstart.pyをダウンロードします。

  3. ダウンロードしたquickstart.pyをお好きなエディタで開き、27行目にあるURLをOAuth同意画面で設定したスコープに修正して上書き保存します。

    # 編集前
    SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
    
    # 編集後
    SCOPES = ['https://www.googleapis.com/auth/drive']
    
  4. Google Cloud のコンソールからダウンロードしてきた credentials.jsonquickstart.py を同じ階層のディレクトリに置いたあと、スクリプトを実行します。

    # 同じ階層にファイルを置く
    ls -l./
    total 16
    -rw-r--r--@ 1 hoge  hoge   402 Oct 15 22:20 credentials.json
    -rw-r--r--@ 1 hoge  hoge  2690 Oct 16 23:30 quickstart.py
    
    # スクリプトを実行する
    python3 quickstart.py
    
  5. スクリプトを実行するとWebブラウザが開き、認証画面が表示されるので認証を通したいGoogleアカウントを選択します。

  6. 続行を押します。

  7. 画面に以下の表示が出たらウィンドウを閉じます。

  8. スクリプトを実行した場所でGoogleDriveのファイルの一覧が表示されたあと、 token.json が生成されていることを確認します。

    # 成功するとGoogleDriveにあるファイルの一覧が表示されます。
    Files:
    810001028765.jpg (14oUwILh5LvIHE***********)
    810001028764.jpg (1_VyC2Df5ecRrm***********)
    810001028763.jpg (1yRdJQk8Opu7ms***********)
    810001028762.jpg (1_jWbp5ZA3HLFF***********)
    810001028761.jpg (1GfbE0YRcfLeDG***********)
    810001028760.jpg (1vlWt61Lt4v1cf***********)
    
    
    # 同じ階層にtoken.json が生成されます。
    ls -l
    total 24
    -rw-r--r--@ 1 hoge  hoge   402 Oct 15 22:20 credentials.json
    -rw-r--r--@ 1 hoge  hoge  2690 Oct 16 23:30 quickstart.py
    -rw-r--r--@ 1 hoge  hoge   645 Oct 16 23:31 token.json     #<------ これ
    

動作テスト

ファイルの一覧を取得する

token.json ファイルを使ってGoogleDriveの一覧を取得してみます。

  1. 先ほどのquickstart.pyを少しいじって、以下のようなスクリプトを作成します。

    sample-get-file-list.py
    import os.path
    
    from google.auth.transport.requests import Request
    from google.oauth2.credentials import Credentials
    from google_auth_oauthlib.flow import InstalledAppFlow
    from googleapiclient.discovery import build
    from googleapiclient.errors import HttpError
    
    SCOPES = ['https://www.googleapis.com/auth/drive']
    
    
    def main():
        creds = None
    
        if os.path.exists('token.json'):
            creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    
        if not creds or not creds.valid:
            # Tokenの有効期限が切れていれば更新
            if creds and creds.expired and creds.refresh_token:
                creds.refresh(Request())
            with open('token.json', 'w') as token:
                token.write(creds.to_json())
    
        try:
            service = build('drive', 'v3', credentials=creds)
    
            # Drive v3 APIの呼び出し
            results = service.files().list(
                pageSize=10, fields="nextPageToken, files(id, name)").execute()
    
            items = results.get('files', [])
    
            if not items:
                print('No files found.')
                return
            print('Files:')
            for item in items:
                print(u'{0} ({1})'.format(item['name'], item['id']))
        except HttpError as error:
            print(f'An error occurred: {error}')
    
    
    if __name__ == '__main__':
        main()
    
  2. スクリプトを実行して、ファイル一覧が取得できれば成功です。

    python3 sample-get-file-list.py
    
    #実行結果
    Files:
    810001028765.jpg (14oUwILh5LvIHE***********)
    810001028764.jpg (1_VyC2Df5ecRrm***********)
    810001028763.jpg (1yRdJQk8Opu7ms***********)
    810001028762.jpg (1_jWbp5ZA3HLFF***********)
    810001028761.jpg (1GfbE0YRcfLeDG***********)
    810001028760.jpg (1vlWt61Lt4v1cf***********)
    

Tips

CUI環境でGoogleDriveAPIを使いたい場合

GUI環境のマシンでtoken.jsonを生成して、それをCUI環境に持って行けばOKです。
実行環境ごとにtoken.jsonを生成しなくても大丈夫です。

tokenには有効期限がある

token.jsonのファイルの中身を見るとわかるのですが、有効期限があります。
これは、quickstart.py の44行目にある処理で更新することが可能です。

# quickstart.py の44行目の処理
creds.refresh(Request())

その他

quickstart.py の中身をよく見るとエラーハンドリングなどがよく出来ている気がしますので、
もしGoogle Cloud API を使った処理を書きたい場合は quickstart.py を移植してから他の処理を追加する方が良いと思います。

Discussion