やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

PythonでFusionTablesにInsertする

前回のつづき。

開発環境

ソースコード

ファイル名 概要
FusionTablesInsert.py FusionTablesAPIを叩く
GetAccessTokenFromRefreshToken.py refresh_tokenからaccess_tokenを取得する

FusionTablesInsert.py

#!python3
#encoding:utf-8

import os.path
import requests
import urllib.parse
import json
import GetAccessTokenFromRefreshToken

client_id = "aaaaaaaaaaaaaaaaaaaaaaaaaa"
client_secret = "bbbbbbbbbbbbbbbbbbbb"
api_key = 'ccccccccccccccccccc'
tableid = 'ddddddddddddddddddddddd'
refresh_token = 'eeeeeeeeeeeeeeeeeeee'

class FusionTablesAPIRunner:
    def __init__(self):
        self.refresh_token = refresh_token
        self.access_token = ""
        self.token_file_path = "Google.OAuth2.AccessToken.{0}.json".format(client_id)

    def initialize(self):
        if os.path.exists(self.token_file_path):
            file = open(self.token_file_path, 'r', encoding='utf-8')
            j = json.loads(file.read())
            file.close()
            self.access_token = j["access_token"]
        else:
            self.request_new_access_token()

    def request_new_access_token(self):
        req = GetAccessTokenFromRefreshToken.AccessTokenRequester()
        token = req.get_token(client_id, client_secret, refresh_token)
        self.access_token = token["access_token"]
        
        file = open(self.token_file_path, 'w', encoding='utf-8')
        file.write(json.dumps(token))
        file.close()

    def insert_request(self):
        sql = "INSERT INTO %s (Timestamp, CpuTemperature) values('%s',%s)" % (tableid, '2016-12-01 01:02:03',44444)
        headers={'Content-Type':'application/json'}
        data = {
            "sql": sql
        }
        url = 'https://www.googleapis.com/fusiontables/v2/query?' + 'key=' + urllib.parse.quote(api_key) + '&' + 'access_token=' + urllib.parse.quote(self.access_token) + '&' + 'sql=' + urllib.parse.quote(sql)
        return requests.post(url, data=data, headers=headers)

    def insert(self):
        r = self.insert_request()
        
        if not(r.status_code == 200):
            print("Error: {0}\n".format(r.status_code))
            print(r.text)
            if (self.is_old_asscess_token(r)):
                self.request_new_access_token()
                r = self.insert_request()
                print(r.text)

        filePath = "Google.FusionTables.query.sql.insert.json"
        file = open(filePath, 'w', encoding='utf-8')
        file.write(r.text)
        file.close()

    def is_old_asscess_token(self, response):
        if (response.status_code == 401):
            j = json.loads(response.text)
            errors = j["error"]["errors"][0]
            if (errors["reason"] == "authError" and 
                errors["message"] == "Invalid Credentials" and
                errors["location"] == "Authorization"
            ):
                return True
            else:
                return False


if __name__ == "__main__":
    run = FusionTablesAPIRunner()
    run.initialize()
    run.insert()

GetAccessTokenFromRefreshToken.py

#!python3
#encoding:utf-8

import requests
import json

class AccessTokenRequester:
    def __init__(self):
        pass
    
    def get_token(self, client_id, client_secret, refresh_token):
        data = {
            "client_id": client_id,
            "client_secret": client_secret,
            "refresh_token": refresh_token,
            "grant_type": "refresh_token"
        }
        r = requests.post('https://www.googleapis.com/oauth2/v4/token', data=data)
        return json.loads(r.text);
    
    def get_access_token(self, client_id, client_secret, refresh_token):
        j = get_token(self, client_id, client_secret, refresh_token)
        return j["access_token"]

必要なもの

Fusion Tables

  • document_id

OAuth2.0認証

  • client_id
  • client_secret
  • api_key
  • code
  • refresh_token
  • access_token

実行までの手順

GoogleAPIを叩くまでにはOAuth2.0認証が必要。こいつがとてつもなく面倒でわかりにくい。何度でもメモる。

  1. Google Account作成
  2. FusionTablesでテーブルを作成する
  3. Google Developer CenterにてClientId, ClientSecret, APIKey作成
  4. Pythonでローカルサーバ立ち上げ
  5. GoogleのRefreshTokenを取得するコード(python3版)入手して実行
    1. コンソールに表示されたURLコピーする
    2. ブラウザ起動しロケールバーにペーストする
    3. 手動で許可ボタン押下する
    4. 手動でcodeコピーする
    5. コンソールにペーストする
    6. RefreshTokenがjsonファイルで保存される
  6. 手動でRefreshTokenコピペ(今回ソースコードへ)
    1. テキストエディタjsonファイルを開く
    2. refresh_tokenの値をコピーする
    3. refresh_tokenの値をコピーする
    4. 今回のコードFusionTablesInsert.py内のrefresh_tokenに代入する
  7. 今回のコードFusionTablesInsert.pyを実行する

以後、FusionTablesInsert.pyを実行すればFusionTablesにデータを挿入する。

課題

  • OAuth2.0認証の手順が難しく面倒
    • 再現手順が長い&難しい&わかりにくい&忘れる。OAuth2.0自体が複雑だしGoogleの実装仕様調査も必要。調査だけで時間がかかる。
    • ソースコードを編集せねばならない。Python解読する知識が必要
    • Pythonのインストールやコードの実行が必要。ワンクリックでやりたい
    • 自動化や一元管理がしたいがセキュリティ的に問題あるかも?

OAuth2.0について何も知らなくてもGoogleAPIを叩けるくらいが理想。

  • CPU温度パラメータをもらって実行したい

今は固定値をInsertするようにしているが、引数をうけとるようにしたい。

所感

ラズパイCPU温度ロガーの実装に近づいてきた。