ラズパイからPyhtonでGoogleスプレッドシートやドライブにアクセスする方法
Contents
Googleスプレッドシートへのアクセス
Raspberry Pi から Python でGoogleスプレッドシートへアクセスする方法は以前の記事「RaspberryPi 3 Model B+からGoogleスプレッドシートへアクセスする方法」でも書いた事がある。
その時は認証に oauth2client モジュールを使用したのだが、oauth2client のドキュメントを見ると “oauth2client is now deprecated. No more features will be added to the”(oauth2clientは非推奨になりました。 これ以上の機能は追加されません) とあったので、現在推奨されている google.oauth2 での認証にプログラムに書き直した。
またGoogle Cloud Platform でのサービスアカウントの取得の際の画面遷移も変わっていたのでこの記事に残しておくことにする。
概要図
今回、下記の様なテストプログラムを作成してみた。
- Raspberry Pi 4B からPythonでGoogleのリソースにアクセスする
- Googleのサービスアカウントで認証する
- 認証モジュールはGoogle Drive、Googleスプレッドシート共に google.oauth2 を使用する
- Google Drive に画像ファイルを書き込む(アップロードする)
- Googleスプレッドシートを読んで該当行を検索して設定値1の値を2倍にして設定値2に書き込む
環境
今回テストした環境は以下の通り。
ラズパイ | Raspberry Pi 4B |
OS | Raspberry Pi OS 32Bit |
言語 | Python 3.7 |
認証 | Googleのサービスアカウントによる認証 |
認証モジュール | google.oauth2 |
事前設定
事前設定の手順は以下の通り。
- Google Cloud Platformでプロジェクトの作成
- 使用するAPIの有効化
- 認証情報の作成
- 秘密鍵の作成
- Google Driveのフォルダーとスプレッドシートの準備
- フォルダーに対する共有設定
Google Cloud Platform
プロジェクトの作成
Google Cloud Platformにてログインをして「プロジェクトの選択」から「新しいプロジェクト」をクリックする。
無料アカウントでは最大10個のプロジェクトを作成することができる。
- プロジェクト名:GoogleOAuthProject
- プロジェクトID:デフォルトで値が設定されるが変更したい時は編集をクリックする
- プロジェクトID:小文字のみ、先頭は数字はNG
- 場所:(個人アカウントなので)組織なし
を設定して「作成」ボタンをクリックする。
プロジェクトが作成される。
APIの有効化
Google DriveとGoogleスプレッドシートにアクセスする為のAPIを有効する。
左のメニューからAPIとサービスー>ライブラリを選択する。
検索欄で”sheet”と入力すると絞り込み検索で Google Sheet API が表示されるので選択する。
「有効にする」ボタンをクリックする。
Google Sheet APIが有効化された。
同様の手順でGoogle Drive APIを検索して有効化する。
有効化された。
メニューからAPIとサービスー>ダッシュボードを選択した後、下の方へスクロールすると有効になっているAPIの一覧が表示されている。
Google Drive APIとGoogle Sheets APIが一覧に表示されていることが確認できる。
その他のAPIはデフォルトで最初から有効化されているAPIだ。
認証情報の作成
Google Drive及びスプレッドシートにアクセスする為の認証情報(サービスアカウント)の作成を行う。
メニューからAPIとサービスー>認証情報を選択する。
+認証情報を作成ー>サービスアカウントを選択する。
尚、上部に “必ず、アプリケーションに関する情報を使用して OAuth 同意画面を構成してください。” のメッセージが表示されているがサービスアカウントでGoogleのリソースにアクセスするのであれば、構成は不要。
OAuth クライントIDで認証する場合は同意画面の構成は必須となる。
- サービスアカウント名:任意の名前を設定する
- サービスアカウントID:サービスアカウント名に応じて自動で設定される(変更可能)
- サービスアカウント説明:説明を記述する
「完了」ボタンをクリックする。
尚、下記の2つについては省略可能なので設定する必要は無いが、設定をしたければ「完了」では無く「作成」ボタンをクリックすれば設定ができる。
- このサービスアカウントにプロジェクトへのアクセスを許可する
- ユーザにこのサービスアカウントへのアクセスを許可
サービスアカウントが作成された。
一覧に表示されない時は F5 でリロードすれば表示される。
秘密鍵の作成
一覧に表示されたサービスアカウントをクリックするとサービスアカウントメニューに遷移するので”キー”タブをクリックする。
鍵を追加ー>新しい鍵を作成を選択する。
キーのタイプは JSON を選択して作成をクリックする。
秘密鍵をプログラムディレクトリの配下に cert ディレクトリを作成して oauthxxxxxx.json(xxxxxxの部分は任意)のファイル名で保存する。
このファイルは後ほどプログラム中で使用する。
秘密鍵が作成されたメッセージが表示されるので閉じるをクリックする。
以上でGoogle Cloud Platform側の設定は終了。
Google Driveとスプレッドシートの準備
続いて画像ファイルを書き込む Google Drive とGoogleスプレッドシートを準備をする。
マイドライブ配下に “RaspberryPi” のフォルダーと “Google Sheetへの書き込みテストシート” の Google スプレッドシートを作成する。
またドライブを選択した状態でURL欄に表示されるドライブIDをプログラム中で使用するので保存しておく。
Googleスプレッドシートは下記の通り。
1列目に端末ID、2列目に設定値1、3列目に設定値2があり設定値1の値を2倍して設定値2に書き込む事とする。
URL欄のファイルID(docs.google.com/spreadsheets/c/ 以降で /edit#gid=0 の前にある文字列)をプログラム中で使用するので保存しておく。
尚、ドライブIDもファイルIDも名前の変更やフォルダーの移動を行っても変更されないのとユニークな値なのでプログラム中から指定する時は扱いやすい。
共有設定
Drive に対して共有設定を行う。
Drive に共有設定を行えればその配下にあるGoogleスプレッドシートにも同様の共有設定が継承される。
先程の手順で保存した秘密鍵の JSONファイルをテキストエディターで開いて client_email 欄をコピーする。
RaspberryPi フォルダーを選択して右クリックー>共有を選択する。
共有欄に先程のメールアドレスを貼り付けて Enter を押下する。
※ここでうっかり「完了」ボタンをクリックすると共有設定が追加されずに終了してしまうので注意!
権限が “編集者” になっていることを確認してい「送信」ボタンをクリックする。
以上でGoogle Drive 側の設定は終了。
RaspberryPiの設定
デフォルトを Python3.x に変更
コマンドラインから python と打った時に Python3.x が起動するように「RaspberryPiでPythonのデフォルトをPython2.7からPython3に変更する」の記事を参照して、Python のデフォルトを 2.x から 3.x に変更する。
必要なモジュールのインストール
プログラム中で使用するモジュールをインストールする。
gspread
Googleスプレッドシート操作用のモジュールを以下のコマンドでインストールする。
sudo pip3 install gspread
google-api-python-client
Python用の Google API Client ライブラリーを以下のコマンドでインストールする。
sudo pip3 install google-api-python-client
以前は oauth2client をインストールしていたが非推奨になったので Google-api-python-client を使用する。
ディレクトリー構造
以下のディレクトリ構成でプログラムや認証ファイルを格納した。
├─$HOME/.local/
│ │
│ ├─oauth-sample
│ │ │ GoogleDriveAndSheetTest.py
│ │ │
│ │ ├──cert
│ │ │ oauthxxxxxx.json
│ │ │
│ │ ├──images
│ │ │ test.JPG
│ │ │
プログラム類は $HOME/.local/(/home/pi/.local/) 配下にプログラム用のディレクトリーを作成して保存した。
自分しか使わないテストプログラムなのでこのディレクトリーに保存しているが、恒久的に使用するプログラムであれば /usr/local/ に保存するのが良いと思う。
GoogleDriveAndSheetTest.py | Google DriveとGoogleスプレッドシートに対して読み書きをするサンプルプログラム(Python) |
oauthxxxxxx.json | 先程の手順で保存したJSON形式の秘密鍵ファイル |
test.JPG | Google Drive に書き込む用の画像ファイル |
プログラム
Python のプログラムは以下の通り。
ソースコード
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 25 11:01:31 2021
・google.oauth2認証
・Google Driveへのファイルのアップロード
・Googleスプレッドへの読み込み・書き込みテストプログラム
@author: Souichirou Kikuchi
"""
import gspread
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
KEY_NAME = './cert/oauthxxxxxx.json' # Google認証キー
GOOGLE_FOLDER_ID = 'Google Drive Folder ID' # Google DriveのフォルダーID
GOOGLE_SHEET_ID = 'Google Sheet ID' # Google SheetのID
IMAGE_DIR = './images/' # 画像ファイルが格納されているローカルのディレクトリー
IMAGE_FILE = 'test.JPG' # Google Driveにアップロードする画像ファイル
TERMINAL_ID = 'SK-RPi002' # 端末ID
try:
if __name__ == '__main__':
scope = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive'] # スプレッドシートとドライブに対するフルアクセス権限
credentials = service_account.Credentials.from_service_account_file(filename=KEY_NAME, scopes=scope)
service = build('drive', 'v3', credentials=credentials) # Drive書き込み
query = "name = '{}' and '{}' in parents and trashed=false".format(IMAGE_FILE, GOOGLE_FOLDER_ID)
res = service.files().list(q=query).execute()
if len(res['files']) == 0: # 存在チェック(フォルダーに同名のファイルが存在していなければ)
media_body = MediaFileUpload(IMAGE_DIR + IMAGE_FILE, mimetype='image/jpeg', resumable=True)
service.files().create( # ファイル作成
body={'name': IMAGE_FILE, 'mimeType': 'image/jpeg', 'parents':[GOOGLE_FOLDER_ID]},
media_body=media_body,
).execute()
gc = gspread.authorize(credentials) # Google Sheet認証
wks = gc.open_by_key(GOOGLE_SHEET_ID).sheet1 # sheetをオープン
records = wks.get_all_values() # 中身を取り出して配列に保存
for i in range(1, len(records)): # sheetの行数分だけ繰り返す
if records[i][0] == TERMINAL_ID: # 端末IDが一致する行を検索する
double_count = int(records[i][1]) * 2 # 設定値1を2倍する
wks.update_cell(i+1, 3, double_count) # 設定値2を更新する(行、列で指定)
break;
except KeyboardInterrupt:
pass
補足説明
ソースコードにコメントを入れているが、いくつか補足をしておく。
KEY_NAME
先程の手順で保存した JSON形式の秘密鍵の path、ファイル名を指定する。
GOOGLE_FOLDER_ID
先程の手順で保存した該当フォルダーのドライブIDを指定する。
GOOGLE_SHEET_ID
先程の手順で保存したGoogleスプレッドシートのファイルIDを指定する。
open_by_key はキー指定で対象のスプレッドシートを開くメソッド。
他には URL 指定の open_by_url(‘URL’) や open(‘シート名’) 等のメソッドもある。
scope
今回は ‘https://www.googleapis.com/auth/spreadsheets’ と ‘https://www.googleapis.com/auth/drive’ の2つを指定している。
Googleスプレッドシートの編集をする為には spreadsheets の他に何故か drive の scope 指定が必要だった。
Google Drive への書き込みだけであれば https://www.googleapis.com/auth/drive.file だけでOKだ。
scope はセキュリティ対策上、不要な権限はなるべく与えないのが基本だと思う。
Google Sheets API(v4)の一覧は以下の通り。
詳細はこちらのGoogleの資料を参照して欲しい。
https://www.googleapis.com/auth/drive | すべての Google Drive の参照、編集、作成、削除 スプレッドシートの編集時には何故かこの権限が必要になる |
https://www.googleapis.com/auth/drive.file | このアプリでオープン、または作成したファイルとフォルダの参照と管理 Google Drive にファイルを書き込むだけであればこの権限でOK |
https://www.googleapis.com/auth/drive.readonly | Google Drive ファイルの参照とダウンロード |
https://www.googleapis.com/auth/spreadsheets | Googleスプレッドシートの参照、編集、作成、削除 |
https://www.googleapis.com/auth/spreadsheets.readonly | Googleスプレッドシートの参照(更新をしない場合) |
実行結果
プログラムの実行は Raspberry Pi 4B の LXTerminal から以下のコマンドを実行する。
python GoogleDriveAndSheetTest.py
- Google Drive に画像ファイル(test.JPG)をアップロードする
- Googleスプレッドシートの端末ID=SK-RPi002の行の設定値1の値を2倍して設定値2にセットする
実行の様子は以下の動画を確認して欲しい。
以上で今回の記事を終了とする。
この記事が何処かで誰かの役に立つことを願っている。
尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。
1件の返信
[…] Google Cloud PlatformのGoogole Drive上のSpread sheetを活用する方法についてはこちらのサイトを参考にしました。”ラズパイからPyhtonでGoogleスプレッドシートやドライブにアクセスする方法” […]