見出し画像

Python+GCPでスプシ/ドライブ連携

スプシをDB、ドライブをNASにする

もちろんRDBMSやNoSQLよりは連携も遅いが、個人で使うアプリ程度ならDBを気軽に見られる方が便利かもしれないと思いやってみた。

GCPでsecretを作成、OAuthする

GoogleDriveAPIはOAuthが必要。
スプシ操作だけであれば、OAuthはなくても、サービスアカウントの作成だけでいける。

OAuthはいろいろ見たが、この記事が一番良かった

他にもこれこれこれも分かりやすい。
個人的には

pip install PyDrive2

と簡単なスクリプトを実行するだけなのが好き。

GCPで作成したsecretをもとに以下を実行して、

.py

from pydrive2.auth import GoogleAuth
from pydrive2.drive import GoogleDrive

gauth = GoogleAuth()
gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth)

OAuth画面で同意することで、credentialファイルがダウンロードされ、2回目以降の認証をスキップできる。

settings.yaml

client_config_file: client_secrets.json
save_credentials: True
save_credentials_backend: file
save_credentials_file: saved_credentials.json
get_refresh_token: True

詳細は省くが、secretのjsonとcredentialのyamlファイル名はPyDrive2内で決まった名前で判断しているらしく、同名にしないと動かないので注意。

この状態で準備OK

プロジェクトのAPIとサービスにて、認証情報を確認する。
以下のように、
1️⃣OAuth2.0クライアントが登録されていることと(DriveAPIの認証用)
2️⃣サービスアカウントが作成されていること(スプシ連携の共有用。このアカウントがスプシを操作する)

また
3️⃣OAuth同意画面がデプロイされていること(公開ステータスが本番環境であること)
※初めてのデプロイには時間がかかることもあるので、PyDrive2でcredentialファイルダウンロードしにいってもなかなか進まないこともある。気長に待ってからリトライしてください。

基本的にはデフォで有効だと思うが


ここから、以下2つのAPIライブラリが有効になっている必要もある。

共通処理にしておこう

フォルダ構成はこんな感じ。

上3つのjsonは鍵で、gapi.pyが本体だ。

スプシ連携はこんな感じ。
連携対象のスプシには、あらかじめサービスアカウントのメールアドレスを共有しておく必要がある。
私の開発中のアプリでは以下のように登録を促し、連携許可を得ている
(スプシのキーはURLから正規表現)

.py

# ServiceAccountCredentials:Googleの各サービスへアクセスできるservice変数を生成します。
from oauth2client.service_account import ServiceAccountCredentials
import gspread
from pydrive2.auth import GoogleAuth
from pydrive2.drive import GoogleDrive
import os.path

class GApi:

    def getSpreadSheet(self, sheet_key):
        """sheet_keyにスプシのキーを入れる
           workbook = GApi().getSpreadSheet("XXXXXXXX") とかってできる
        """
        # 実行中のファイルのとこに移動, ここにトークンがある想定
        # スプシのサービスアカウントの、flowingうんたらのjsonトークンを参照
        os.chdir(os.path.dirname(os.path.abspath(__file__)))

        # 2つのAPIを記述しないとリフレッシュトークンを3600秒毎に発行し続けなければならない
        scope = [
            'https://spreadsheets.google.com/feeds',
            'https://www.googleapis.com/auth/drive'
        ]

        # 秘密鍵ファイル名
        secret_key = 'flowing-density.json'
        # 秘密鍵から認証情報設定
        credentials = ServiceAccountCredentials.from_json_keyfile_name(secret_key, scope)
        # OAuth2の資格情報を使用してGoogle APIにログイン
        gc = gspread.authorize(credentials)

        # スプレッドシートを開く
        try:
            workbook = gc.open_by_key(sheet_key)
            return workbook
        except:
            return None

    def getLastRow(self, worksheet):
        """スプシ操作の例
        """
        # A1:A100のうち, 最も上の空白の行数を取得
        chkRange = worksheet.range('A1:A100')
        target_row = 0
        for idx, val in enumerate(chkRange):
            if val.value == '':
                target_row = idx + 1
                break
        return target_row if target_row != 0 else None

また、Drive APIも共通化するとこんな感じ。
格納先のフォルダのIDを指定しておくと、あとでファイルを見つけやすい。

.py

    def upFile(self, name, mime):
        # トークン参照のため、起動中フォルダに移動. 直下のsecretsとcredentialsを参照
        os.chdir(os.path.dirname(os.path.abspath(__file__)))
        gauth = GoogleAuth()
        gauth.LocalWebserverAuth()
        #gauth.CommandLineAuth() なくてもいい
        drive = GoogleDrive(gauth)

        folder_id = 'XXXXXXX' Driveのフォルダのキー
        file = drive.CreateFile({'title': name, 'mimeType': mime, 'parents': [{'id': folder_id}]})
        file.SetContentFile(name)
        file.Upload()

ちなみにGoogleDrive上のファイルは、Windowsなどとは異なり
ファイル名がユニークキーではなく、あくまで割り振られたIDがユニークキーのため
ガンガン名前が重複する。注意されたし。

レポ

secret系があるのでGASをそのまま公開はできませんが
一応githubに挙げているのでおいておきます。

python+seleniumでWebサイトから値/スクショを取得し
スプシに値、Driveに画像ファイルを連携するサンプルです。

https://qiita.com/neras_1215/items/9f0d24f1396ef5520f57

ALHについて知る



↓ ↓ ↓ 採用サイトはこちら ↓ ↓ ↓


↓ ↓ ↓ コーポレートサイトはこちら ↓ ↓ ↓


↓ ↓ ↓ もっとALHについて知りたい? ↓ ↓ ↓