ラズパイからPyhtonでGoogleスプレッドシートやドライブにアクセスする方法 | そう備忘録

ラズパイからPyhtonでGoogleスプレッドシートやドライブにアクセスする方法

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 でのサービスアカウントの取得の際の画面遷移も変わっていたのでこの記事に残しておくことにする。

概要図

今回、下記の様なテストプログラムを作成してみた。

ラズパイからGoogle DriveやGoogleスプレッドシートに書き込む・概要図
  • 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

事前設定

事前設定の手順は以下の通り。

  1. Google Cloud Platformでプロジェクトの作成
  2. 使用するAPIの有効化
  3. 認証情報の作成
  4. 秘密鍵の作成
  5. Google Driveのフォルダーとスプレッドシートの準備
  6. フォルダーに対する共有設定

Google Cloud Platform

プロジェクトの作成

Google Cloud Platformにてログインをして「プロジェクトの選択」から「新しいプロジェクト」をクリックする。

無料アカウントでは最大10個のプロジェクトを作成することができる。

新しいプロジェクト
  • プロジェクト名:GoogleOAuthProject
  • プロジェクトID:デフォルトで値が設定されるが変更したい時は編集をクリックする
プロジェクト名とプロジェクトID
  • プロジェクトID:小文字のみ、先頭は数字はNG
  • 場所:(個人アカウントなので)組織なし

を設定して「作成」ボタンをクリックする。

プロジェクトIDを設定して「作成」ボタン

プロジェクトが作成される。

プロジェクトが作成された

APIの有効化

Google DriveとGoogleスプレッドシートにアクセスする為のAPIを有効する。

左のメニューからAPIとサービスー>ライブラリを選択する。

APIとサービス、ライブラリー

検索欄で”sheet”と入力すると絞り込み検索で Google Sheet API が表示されるので選択する。

Google Sheet APIの検索

「有効にする」ボタンをクリックする。

「有効にする」ボタンをクリックする。

Google Sheet APIが有効化された。

Google Sheet APIの有効化

同様の手順でGoogle Drive APIを検索して有効化する。

Googe Drive APIの検索

有効化された。

Googe Drive APIが有効化された

メニューからAPIとサービスー>ダッシュボードを選択した後、下の方へスクロールすると有効になっているAPIの一覧が表示されている。

Google Drive APIとGoogle Sheets APIが一覧に表示されていることが確認できる。

有効化されているAPIの一覧

その他のAPIはデフォルトで最初から有効化されているAPIだ。

認証情報の作成

Google Drive及びスプレッドシートにアクセスする為の認証情報(サービスアカウント)の作成を行う。

メニューからAPIとサービスー>認証情報を選択する。

認証情報の作成

+認証情報を作成ー>サービスアカウントを選択する。

尚、上部に “必ず、アプリケーションに関する情報を使用して OAuth 同意画面を構成してください。” のメッセージが表示されているがサービスアカウントでGoogleのリソースにアクセスするのであれば、構成は不要。

OAuth クライントIDで認証する場合は同意画面の構成は必須となる。

+認証情報の作成、サービスアカウント
  • サービスアカウント名:任意の名前を設定する
  • サービスアカウントID:サービスアカウント名に応じて自動で設定される(変更可能)
  • サービスアカウント説明:説明を記述する

「完了」ボタンをクリックする。

尚、下記の2つについては省略可能なので設定する必要は無いが、設定をしたければ「完了」では無く「作成」ボタンをクリックすれば設定ができる。

  • このサービスアカウントにプロジェクトへのアクセスを許可する
  • ユーザにこのサービスアカウントへのアクセスを許可
サービスアカウントの詳細を入力して作成

サービスアカウントが作成された。

一覧に表示されない時は F5 でリロードすれば表示される。

サービスアカウントが表示される

秘密鍵の作成

一覧に表示されたサービスアカウントをクリックするとサービスアカウントメニューに遷移するので”キー”タブをクリックする。

サービスアカウントメニューが表示されるのでキータブをクリックする

鍵を追加ー>新しい鍵を作成を選択する。

新しい鍵を作成

キーのタイプは JSON を選択して作成をクリックする。

キーのタイプは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も名前の変更やフォルダーの移動を行っても変更されないのとユニークな値なのでプログラム中から指定する時は扱いやすい。

Googleスプレッドシート

共有設定

Drive に対して共有設定を行う。

Drive に共有設定を行えればその配下にあるGoogleスプレッドシートにも同様の共有設定が継承される。

先程の手順で保存した秘密鍵の JSONファイルをテキストエディターで開いて client_email 欄をコピーする。

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
gspreadのインストール

google-api-python-client

Python用の Google API Client ライブラリーを以下のコマンドでインストールする。

sudo pip3 install google-api-python-client

以前は oauth2client をインストールしていたが非推奨になったので Google-api-python-client を使用する。

Google APIのインストール

ディレクトリー構造

以下のディレクトリ構成でプログラムや認証ファイルを格納した。

├─$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のアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

1件の返信

  1. 2022年8月6日

    […] Google Cloud PlatformのGoogole Drive上のSpread sheetを活用する方法についてはこちらのサイトを参考にしました。”ラズパイからPyhtonでGoogleスプレッドシートやドライブにアクセスする方法” […]

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。