Google Fusion Tables APIについて調べてみた。select文の発行はできたが、insert文は失敗した。
目標
ラズパイのCPU温度を定期的にロギングしてアップロードしたい。
対象環境
- Firefox 50.0
- Google Account
- Google Developers Console
- Google Drive
- Google Fusion Tables
資料をみてみる
資料は英語のため、読むのに苦労しそう。
- 開発者用のFusionTablesページへアクセスする。
ガイド
をクリックするUse the API
をクリックする
認証など基本的なことはUse the APIページに書いてありそう。
認証方法
認証方法 | 説明 |
---|---|
OAuth 2.0 | 許可が必要な場合(プライベートデータ) |
API key | 承認が不要な場合(公開データ) |
二種類を使い分けることができるらしい。 翻訳したが、"許可"と"承認"は同じことをいっているという認識でいいのだろうか。
おそらく、GoogleDocumentでの公開や共有の設定で、自分だけ
/全員
のようなことをプライベート/公開データと言っているのだろう。全員に公開すれば、API keyを渡して承認不要で実行できるということでいいのだろうか。
認証の流れ
OAuth2.0認証のみ対応しているらしい。 気になったのはOAuth2.0認証が以下のような流れであると書いてあること。
- scopeを指定してリクエストする
- ユーザへの同意画面が表示される
- 承認した場合、アクセストークンを提供する
- アクセストークンを使ってAPIをリクエストする
すべてのアプリケーションタイプに適用されるらしい。 API keyを使っても、承認画面が必要ということだろうか?
Google Sign-inを使っている場合、認可の一部が自動化されるらしいが。Google Sign-inとやらが何なのか知らない。
サンプルコード
こちらにサンプルコードがあるらしい。
試してみる
https://www.googleapis.com/fusiontables/v2/tables/{DocumentId}/columns?key={API key}
をGETする。テーブルのカラム情報をとるAPIらしい。とりいそぎブラウザのロケールバーで叩く。
項目 | 内容 |
---|---|
{DocumentId} |
以前作成したFusionTableファイルのURLパラメータキーdocid の値。 |
{API key} |
前回作成したAPIKey。 |
Login Required
しかし、以下のエラーになった。
{ "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } }
エラー内容をみると、HTTPヘッダにAuthorization
情報を設定しろといっているように見える。
たしかOAuth認証では、ログインするとAccessTokenが配布される。それをHTTPヘッダに設定しろということだろう。たぶん。
やなこった。認証なんてしたくない。サクっと実行したいんじゃ。
公開範囲
FusionTablesの公開範囲を変更してみる。公開範囲を広げると認証不要になると思う。
リンクの共有
概要 | 説明 |
---|---|
ウェブ上で一般公開 | インターネット上の誰でも検索、アクセスできます。ログインは不要です。 |
リンクを知っている全員 | リンクを知っている全員がアクセスできます。ログインは不要です。 |
特定のユーザ | 特定のユーザと共有しています。 |
とりあえず、リンクを知っている全員
にしてみる。
成功
{ "kind": "fusiontables#columnList", "totalItems": 2, "items": [ { "kind": "fusiontables#column", "columnId": 3, "name": "Timestamp", "type": "DATETIME", "description": "CPU温度の取得日時。", "formatPattern": "DT_ISO_YEAR_MONTH_DAY_TIME", "validateData": true }, { "kind": "fusiontables#column", "columnId": 1, "name": "CpuTemperature", "type": "NUMBER", "description": "CPU摂氏温度(1000倍値)。cat /sys/class/thermal/thermal_zone0/temp 取得値。", "formatPattern": "NONE", "validateData": false } ] }
無事、カラム情報が取得できた。
SQL (select)
SQL文を発行してテーブルを操作したい。まずはselect文。
https://www.googleapis.com/fusiontables/v2/query?sql={SQL}&key={APIKey}
の書式。key
は先述のと同じ。SQLはselect文を書く。SELECT * FROM {docid}
の書式。テーブル名の代わりにdocidを使う。
https://www.googleapis.com/fusiontables/v2/query?sql=SELECT * FROM {docid}&key={APIKey}
をブラウザのロケールバーに入力して叩く。
{ "kind": "fusiontables#sqlresponse", "columns": [ "Timestamp", "CpuTemperature" ], "rows": [ [ "2000/01-01 00:00:05", "36000" ], [ "2005/01-01 00:00:08", "38000" ] ] }
成功。テストデータとして入力した値が返ってきた。
SQL (insert)
いよいよ目的のinsert文。
select文のときと同じ。sql部分をinsert文に変更する。INSERT INTO {docid} (Timestamp,CpuTemperature) VALUES ('2016-01-02 03:04:05',3900)
のようにする。
https://www.googleapis.com/fusiontables/v2/query?sql=INSERT INTO {docid} (Timestamp,CpuTemperature) VALUES ('2016-01-02 03:04:05',3900)&key={APIKey}
をブラウザのロケールバーで叩く。
The operation is not supported for GET requests
しかし、以下のようなエラーになった。
{ "error": { "errors": [ { "domain": "fusiontables", "reason": "cannotWriteDataOnGetRequests", "message": "The operation is not supported for GET requests. Please try again using POST." } ], "code": 501, "message": "The operation is not supported for GET requests. Please try again using POST." } }
GETではinsertできない。insertするときはPOSTしろ。ということか。
curl
ブラウザのロケールバーではGETしかできない。仕方ないのでcurlを使ってPOSTする。
set CURL_PEM="C:\Program Files\Git\ssl\certs\cacert.pem" set RESPONSE="GitHub.%USER_NAME%.Authorizations.json" curl --cacert "%CURL_PEM%" -o %RESPONSE% -X POST -F "sql=INSERT INTO {docid} (Timestamp,CpuTemperature) VALUES ('2016-01-02 03:04:05',3900)" -F "key={APIKey}" https://api.github.com/authorizations
SSL certificate problem
例によってCURLのSSL証明書エラー。恒例となりつつある。たまにcurlを使うとこうなる。
rl: (60) SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed More details here: http://curl.haxx.se/docs/sslcerts.html
こちらからダウンロードする。しかし、同様のエラーで改善しなかった。なぜだ。仕方ないので-k
オプションを追加。チェックしないようにする。
curl -k --cacert "%CURL_PEM%" -o %RESPONSE% -X POST -F "sql=INSERT INTO {docid} (Timestamp,CpuTemperature) VALUES ('2016-01-02 03:04:05',3900)" -F "key={APIKey}" https://api.github.com/authorizations
Unsupported content with type
{ "error": { "errors": [ { "domain": "global", "reason": "badContent", "message": "Unsupported content with type: multipart/form-data; boundary=----------------------------418b17b53a26" } ], "code": 400, "message": "Unsupported content with type: multipart/form-data; boundary=----------------------------418b17b53a26" } }
POST内容にケチをつけられたようだ。curlでPOSTの仕方を間違えたっぽい。
こちらを真似た結果失敗した。こちらをよくみてみるとわかりそう。こちらのほうが詳しいか。POSTむずかしい。
curl -k --cacert "%CURL_PEM%" -o %RESPONSE% -XPOST --data-urlencode "sql=INSERT INTO {docid} (Timestamp,CpuTemperature) VALUES ('2016-01-02 03:04:05',3900)" --data-urlencode "key={APIKey}" https://www.googleapis.com/fusiontables/v2/query
Login Required
{ "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } }
またしてもログイン必須エラー。もしやinsertは認証が必須なのだろうか。
Daily Limit for Unauthenticated Use Exceeded
パラメータを1つにまとめて送信してみた。
curl -k --cacert "%CURL_PEM%" -o %RESPONSE% -XPOST --data-urlencode "sql=INSERT INTO {docid} (Timestamp,CpuTemperature) VALUES ('2016-01-02 03:04:05',3900)&key={APIKey}" https://www.googleapis.com/fusiontables/v2/query
{ "error": { "errors": [ { "domain": "usageLimits", "reason": "dailyLimitExceededUnreg", "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.", "extendedHelp": "https://code.google.com/apis/console" } ], "code": 403, "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup." } }
なんと、もはやリクエスト上限らしい。たぶん10回もやっていない。使えなさすぎ。 まだinsert成功していないのに。
こちらによるとFusion Tables APIの上限は1日あたり25,000リクエストらしい。2万5千回もリクエストしていない。25回もしていないはず。
こちらによると、1日2万5千リクエストが上限らしい。Query.sql
は1回あたり5リクエスト消費するらしく、1日あたり5千件になるとか。さらに1テーブル1分あたり30件の書き込みが上限らしい。
1日に5000回もリクエストしてないし、1分あたり30件以内のはず。
所感
結局、insert文の成功までできなかった。insertの場合は認証が必要なのかもしれない。しかしそうなると自動化できなくなってしまうだろう。何らかの手動操作が必要になりそう。それではバッチ処理ができない。
リクエスト上限は当てにならない。GitHubでもそういう印象。認証といいリクエスト上限といい、GoogleAPIは想像以上に使えないのかもしれない。私がわかっていないだけかもしれないが。
どうでもいいが、今年からブログの予約投稿日時を10:00から00:00に変更する。