pyDriveでUbuntuのDockerからGoogle Driveのファイル操作を行う


google-drive-ocamlfuseの問題

google-drive-ocamlfuseを使ってUbuntuのDockerからGoogle Driveをマウントする方法を試してみたのだが、google-drive-ocamlfuseは特別な手続きなしでファイルを操作できる反面、使ってみるとめちゃめちゃ遅くて、小さなファイルのやり取りならなんとかなるが、数十MBのデータの移動などをするとなると実用レベルにないくらい遅い。別の方法も試してみようと思い、pyDriveに行き着く。

pyDriveとは

pyDriveはGoogleのGoogle Drive APIのpython wrapperで、直接APIを呼び出すよりはpythonから呼び出したほうが便利かと思ってこれを試してみる。


Dockerを立ち上げる前に下記のファイルを用意しておく
  • Dockerfile
  • Google APIのClient ID / Client Secret (デスクトップアプリ用のID/Secretを用意)
  • settings.yaml (Google Driveの認証情報などの設定の定義ファイル)
  • gd_pydrive.py (pyDriveのお試しプログラム)

デスクトップアプリ用のClient ID/Client Secretについては作り方をこちらで紹介しています。今回は認証にCommandLineAuth()を使うので"デスクトップアプリ"用のID/Secretを用意してください。

それぞれのファイルは下記。

Dockerfile
FROM ubuntu:latest

RUN apt-get update
RUN apt-get install python3 python3-pip -y
RUN pip3 install pydrive

COPY . /work
WORKDIR /work

とりあえず最低限の構成。ローカルディレクトリに設定ファイル(settings.yaml)とテストプログラム(gd_pydrive.py)を配備しておき、Docker上の/workにコピーする


settings.yaml
client_config_backend: settings
client_config:
  client_id: xxxxx.apps.googleusercontent.com
  client_secret: XXXXxXXXxXXXX

save_credentials: True
save_credentials_backend: file
save_credentials_file: credentials.json

get_refresh_token: True

詳細なオプションは公式マニュアルを参照してもらうとして、
ポイントを説明すると、
  • client_id, client_secretをこのファイルで指定しておく。
  • save_credentialsをTrueにして、ファイルに保存するようにしておくことで次回以降の認証手続きを簡素化させる。
  • get_refresh_tokenをTrueにすることでアクセスするごとにtokenをリフレッシュさせる


gd_pydrive.py
from pydrive.auth import GoogleAuth

gauth = GoogleAuth()
gauth.CommandLineAuth()

調べていると、gauth.LocalWebserverAuth()を使うやり方が多く紹介されているが、ホストのUbuntuからだとうまく行くが、Docker上からだと認証後のリダイレクトがうまく行かず断念。
公式のマニュアルもLocalWebserverAuth()が第一候補だが、 CommandLineAuth() も紹介されており、こちらを使ってみる

You can also use CommandLineAuth() which manually takes code from user at command line.

Docker Image作成+実行


下記コマンドを実行し、Dockerイメージを作成+Dockerを実行
sudo docker build -t gdrive .
sudo docker run  -it gdrive /bin/bash

Docker上でpyDriveをお試し(初回認証)
root@2385921abe7d:/work# python3 gd_pydrive.py
/usr/local/lib/python3.8/dist-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access credentials.json: No such file or directory
  warnings.warn(_MISSING_FILE_MESSAGE.format(filename))
Go to the following link in your browser:

    https://accounts.google.com/o/oauth2/auth?client_id=xxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&response_type=code&approval_prompt=force

Enter verification code: xxxxxxxxxxxxxxxxxxxxxxxx
Authentication successful.



同じディレクトリにcredentials.jsonが生成され、次回からブラウザによる認証なしで行ける
root@536122a820a4:/work# ls -l
-rw------- 1 root root 1286 Sep 20 13:38  credentials.json
-rw-rw-r-- 1 root root  306 Sep 20 12:57  gd_pydrive.py
-rw-rw-r-- 1 root root  296 Sep 20 12:57  settings.yaml

認証は通るようになったので次回はファイル操作をしてみて性能を見てみることとする。