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について知りたい? ↓ ↓ ↓