表題の件について再現可能なように情報をまとめておく。
目標
ラズパイのCPU温度を定期的にロギングしてアップロードしたい。
小目標
PythonからFusionTablesAPIを使ってinsertする。
前回
PythonでOAuth2.0とFusionTablesAPIによるinsertができた。ついに小目標を達成した。
しかし、目標を達成することはできない。OAuth2.0では手入力が必要になってしまうためである。
対象環境
- Windows XP Pro SP3 32bit
- Python 2.7
- コンソール
- Firefox 50.0
- Google Account
- Google Developers Console
- Google Drive
- Google Fusion Tables
Googleのドキュメント
OAuth 2.0
Using OAuth 2.0 to Access Google APIsにてOAuth2.0の概要を参照する。
Fusion Tables API
Fusion Tables API v2にてWebAPIの仕様を参照する。
Google API Client Libraries
Google API Client LibrariesにてPythonからGoogleAPIを使用するライブラリの使い方を参照する。
環境の準備
ローカルツール
- ブラウザ
- Firefox 50.0
- Python
- Python 2.7.10
- スクリプト言語を乗り換えるべきかどうか考えたとき、GitHubとSSL/TLS通信できそうなバージョンが2.7.10以上らしいため
- Python 3.4.4(任意)
- PythonでHTTP通信する方法について調べてみたとき、Windows XPで動き、かつmsi installerがある最新バージョンを探した結果
- Python 2.7.10
- コンソール
- Windows XP標準装備のcmd.exeで問題ないはず
- 任意でConEmu/Nyagosなどを用意してもいい
ライブラリ
Google API Client Libraryをインストールしたときの手順を参照。
Webサービス
- Google Accountを作成する
- ログインする
- Google Driveにアクセスする
- GoogleDriveにアプリケーションを追加する
- FusionTablesでテーブルを作成する
- テーブルのURLパラメータである
docid
の値を控える - 共有状態は関係ない?
- Google Developers Consoleにアクセスする
- 認証情報
- Googleの認証キーを取得する
API Key
を作成するAPI Key
を控える
OAuth クライアント ID
を作成するClientId
,ClientSecret
を控える
- Googleの認証キーを取得する
- ダッシュボード
有効にする
Fusion Tables API
を検索し、有効にする
- 認証情報
ソースコード
SimpleSample.py
ファイルとして以下を保存する- 控えたClientId, ClientSecret, API Key, docid(tableid)をそれぞれコードの変数値に埋め込む
#!python2 # https://developers.google.com/fusiontables/docs/samples/python import urllib2, urllib, simplejson, sys, httplib client_id = "*.apps.googleusercontent.com" client_secret = "01234567890123456789" redirect_uri = "http://localhost:8000" api_key = '0123456789012345678901234567890123456789' tableid = '0123456789012345678901234567890123456789' class RunAPITest: def __init__(self): self.access_token = "" self.params = "" def main(self): print "copy and paste the url below into browser address bar and hit enter" print "https://accounts.google.com/o/oauth2/auth?%s%s%s%s" % \ ("client_id=%s&" % (client_id), "redirect_uri=%s&" % (redirect_uri), "scope=https://www.googleapis.com/auth/fusiontables&", "response_type=code") code = raw_input("Enter code (parameter of URL): ") data = urllib.urlencode({ "code": code, "client_id": client_id, "client_secret": client_secret, "redirect_uri": redirect_uri, "grant_type": "authorization_code" }) serv_req = urllib2.Request(url="https://accounts.google.com/o/oauth2/token", data=data) serv_resp = urllib2.urlopen(serv_req) response = serv_resp.read() tokens = simplejson.loads(response) access_token = tokens["access_token"] self.access_token = access_token self.params = "?key=%s&access_token=%s" % \ (api_key, self.access_token) def testInsertV2(self): print "v2 Query.sql insert" sql = "INSERT INTO %s (Timestamp, CpuTemperature) values('%s',%s)" % (tableid, '2011-11-11 11:11:11',11111) data = '''{ "sql": "%s" }''' % (sql) response = self.runRequest( "POST", "/fusiontables/v2/query%s&sql=%s" % \ (self.params, urllib.quote(sql)), data=data, headers={'Content-Type':'application/json'}) json_response = simplejson.loads(response) print(json_response) return json_response def runRequest(self, method, url, data=None, headers=None): request = httplib.HTTPSConnection("www.googleapis.com") if data and headers: request.request(method, url, data, headers) else: request.request(method, url) response = request.getresponse() print response.status, response.reason response = response.read() print response return response if __name__ == "__main__": api_test = RunAPITest() api_test.main() api_test.testInsertV2()
実行する
ローカルサーバを起動する
- コンソールを起動する
- 以下のコマンドを叩く Python2の場合
python -m SimpleHTTPServer [ポート番号(デフォルトは8000)]
Python3の場合
python3 -m http.server [ポート番号(デフォルトは8000)]
このままにしておく。
OAuth2.0認証する
- コンソールを起動する
python SimpleSample.py
でコードを実行する
コンソールに表示された
https://accounts.google.com/...
のURLをコピーするブラウザを起動する
- ブラウザのロケールバーにURLをペーストする
- Enterキーを押下してURLにアクセスする
- 以下のように許可を求める表示が出る
- 内容を確認して、
許可
をクリックする - 以下のようなページが表示される
- URLが
localhost:8000/?code=...
になる code
パラメータの値をコピーする(画面に表示されているものやURL内にある)コンソールに戻る
Enter code (parameter of URL):
で待機しているので、コピーしたURLをペーストする
- Enterキーを押下する
AccessTokenの取得→Fusion Tables APIの実行
- あとはプログラムが実行され、コードにあるとおりinsert文が発行される
- 上記のログから
HTTP 200 OK
が返却されることを確認する - 対象のFusionTablesファイルを参照し、コードでinsertした内容が挿入されていることを確認する
おわり
以上。たぶんこれで再現可能なはず。こまかいところはリンク先を参照。抜けや漏れがないことを祈る。
所感
ゼロからはじめたら一体どれだけ時間がかかることやら…。
準備や手順が長すぎる。たかがWebAPIひとつ叩くために、これだけのサーバ、通信、ソフトウェア、操作が必要なのか。毎回これをやるの?ないわ。