今回はGoogleDriveに格納されているSpreadSheetのデータを、Hopsを使用してGrasshopperから取得してみました。(※HopsはRhino7.4以降使用できるプラグインになりますのでご注意ください)
Grasshopperでスプレッドシートを読み込む方法
GrasshopperでSpreadSheetのデータを読み込む方法はいくつかあるかと思います。
- SpreadSheetをCSVでダウンロードしてローカルで読み込む。
- Google CloudでAPIキーを発行し、Ghpythonコンポーネントからpythonの標準パッケージurllib2を使用してリクエストを送る。
- pythonのライブラリgspread, oauth2clientをインストールし、それらを使い認証処理を行ってからデータを取得する。取得したデータをHopsなどを使ってGrasshopperに渡す。(※つまりGrasshopperでPythonの外部ライブラリをどうにかして使う。)
- そもそもSpreadSheetでデータを管理せず、RDB系などのDBに移行して、サーバー側の言語でAPIを作成してGhpythonからリクエストを送る。
などなど、いろんな方法が考えられるかなと思います。
- 1に関しては最も簡単な方法ですが、データが頻繁に更新されたりチームで共有する場合などは、グローバルに管理して直接取得したくなるかなと思います。
- 2に関しても割と簡単にできますが、認証処理を省いているため、SpreadSheetの設定を「リンクを知っている人全員」が閲覧できる状態にしなけらばならず、外部から見られて困るようなデータは扱えません。
- 3に関しては今回やっていく方法です。自信の環境でPythonの外部ライブラリoauth2clientを使用して認証処理を行ってからスプレッドシートのデータを取得し、Hopsを使用してGrasshopperに渡してあげます。これによって2の様な問題が解消されてます。
- 4に関しては、そもそもSpreadSheetを使わないという選択です。以前記事を書いたのでご興味あれあば以下の記事を読んでみてください。
今回読み込むSpreadSheet

- 今回は、単価のデータをSpreadSheetで管理していることを想定して、上画像のようなデータを用意しました。これらをGrasshopperから取得してみます
準備
まずは外部からSpreadSheetにアクセスできるように準備を行っていきます。(※Googleアカウントがある前提で解説していきます。)


Google Cloud にアクセスして、ログイン後上箇所から、新しいプロジェクトを適当なプロジェクト名で作成します。今回は「grasshopper-spreadsheet」という名前で作成しました。


続いて、検索欄からGoogleDriveAPIとGoogleSheetsAPIを検索し有効にします。


サービスアカウントを作成します。適当な名前・IDを入れて作成します。説明以降は省略できます。


サービスアカウントが作成されたら、アカウントをクリックし、秘密鍵をJSON形式で作成します。JSONファイルがダウンロードされると思いますが、後ほど使用しますのでデスクトップなどに置いておいてください。

- SpreadSheetに移動して、共有ボタンから作成したサービスアカウントを追加します。ユーザー検索欄にサービスアカウントのメールアドレスを入れると検索できるかと思います。
- これでスプレッドシート側の準備は完了です。
Hopsを使用してAPIを作成する
Hops componentを作成していきます。開発環境は以下になります。
- Rhino7.9, conda 22.9.0, Python 3.9.13, Hops0.15.4, Editor : VSCode
anacondaで仮想環境を作成してます。pythonは3.8以上, Rhinoは7.4以上である必要があるのでご注意ください。
Hopsを使用するまでの環境構築は省いてますが、以下の記事や動画がわかりやすく解説してくれてます。ご参照ください。
from flask import Flask
import ghhops_server as hs
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import os
app = Flask(__name__)
hops = hs.Hops(app)
@hops.component(
"/getSpreadsheet",
name="ss",
description="Get sheet value",
inputs=[],
outputs=[
hs.HopsString("value", "value", "fetch value"),
],
)
def getSpreadsheet():
scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
jsonKey = os.path.abspath('各自ダウンロードしたjsonKeyファイル')
credentials = ServiceAccountCredentials.from_json_keyfile_name(jsonKey, scope)
gc = gspread.authorize(credentials)
sheet = gc.open("スプレッドシートの名前").sheet1
getSheet = sheet.get_all_values()
return getSheet
if __name__ == "__main__":
app.run()
上が作成したhops componentになります。app.pyというファイル名で作成してます。
getSpreadSheet関数で一連の処理を書いてます。
- ダウンロードしたJSONキーは上のpythonファイルと同階層において、jsonKeyの行で読み込んでます。ファイル名は各々変わってくるかと思います。
- その後Keyを用いて認証を行い、スプレッドシートを開きsheet1を取得し、sheet1のすべての値を取得して値を返してます。
このファイルを実行すると、 http://127.0.0.1:5000/ でサーバーが起動します。
grasshopperからHopsコンポーネントで http://127.0.0.1:5000/getSpreadsheet アクセスすれば、Grasshopper側で値を取得できます。
Grasshopperから値を取得

- GrasshopperからHopsを使用して値を取得してみます。Hopsコンポーネントをダブルクリックし、 http://127.0.0.1:5000/getSpreadsheet にアクセスすることでデータが取得できましたが、取得したデータに日本語が含まれているので、文字コードをdecodeして文字列に直してあげます。

- app.py側で処理したかったんですが、うまくいかなかったのでしぶしぶGhpythonを使ってdecodeしてます。
response = value.decode('unicode-escape')
これでスプレッドシートの値が取得できました。
おまけ

最後に、取得したデータを少し加工します。
部位・仕上・単価・単位の4項目があり、プラグインhumanのItem Selectorコンポーネントで、部位と仕上でフィルターをかけられるようにしてます。これでほしい値をSelectorで選べるようになってます。
Hops componentに引数を渡してapp.py側で処理することもできるかなと思います。
スプレッドシートと連携する機会はさほどないかもしれませんが、もしかしらたら役に立つかもと思いブログにしておきました。 以上
【参考】