いちろう’s blog

すーぱーえんじにあ

Pythonを用いてタニタのHealth Planet APIの認証トークンを取得する

先日Tanitaの体組成計を購入した。タニタの体組成計の情報はHealthPlanetというアプリと連携させることで、サーバ上にデータが保存される。そのデータは、タニタが提供するAPIを利用することで取得できるため、こちらのデータを利用して日々の体重の変化を記録しようと思ったが、その際に利用するアクセストークンの取得の際にかなり悩んだのでその備忘録。

公式ドキュメントは以下のURLを参照。

購入した体組成計

ClientID、ClientSecretの発行

はじめにAPIの利用開始の登録を行い、ClientID、ClientSecretの発行を行う。URLは以下のリンクを利用する。

ログイン後、以下の画面が表示される。「アプリケーションタイプ」の項目は「クライアントアプリケーション」と設定し、サービス名とメールアドレスを入力する。入力が完了したらAPI利用規約を確認の上、画面下部の「規約に同意して登録する」のボタンをクリック。

f:id:sey323:20210508171613p:plain
アプリケ-ション登録画面1

その後以下の画面に遷移するので、その画面に表示されているClientID、ClientSecretを取得する。

f:id:sey323:20210508171716p:plain
ClientID、ClientSecret取得画面

oauth認証によるアクセストークンの取得

次に取得したClientID、ClientSecretを利用してoauth認証を実施し、APIのアクセスに必要なアクセストークンを取得する。

アクセストークンの取得は、RやMatlab、GoogleAppScirpts等で実装された方法はいくつか見つけたが、アクセストークンの取得のみの方法見つけられなかったり、Python以外の環境構築が手間だった。
アクセストークンは一度取得できれば良いので、今回は以下のようにアクセストークンの取得用スクリプトを作成し、そちらを用いてアクセストークンを取得した。

必要ライブラリはoauthlibのみ

$ pip install oauthlib

以下のコマンドで実行する。

$ python src/fitness/tanita_oauth.py ${ClientID} ${ClientSecret}
https://www.healthplanet.jp/oauth/auth?response_type=code&client_id=${ClientID}&redirect_uri=https%3A%2F%2Fwww.healthplanet.jp%2Fsuccess.html&scope=innerscan&state=Zp92paSQi9Ltfmng3phBiN0Z4hd0dm
上記のURLにアクセスし、取得したコードを入力して、Enterを押してください。
${遷移後の画面で払い出されたコード}
{'access_token': '${アクセストークン}', 'expires_in': 2592000, 'refresh_token': '${リフレッシュトークン}', 'expires_at': 1622965650.782186}
$

実行するとURLが発行され、「上記のURLにアクセスし、取得したコードを入力して、Enterを押してください。」と表示されるので、URLにアクセスすると以下の画面に遷移する。
そこで「アクセスを許可」をクリックする。 f:id:sey323:20210508172018p:plain

次に表示される画面でコードが払い出されるので、そのコードをコンソールに入力しEnterを押下すると、アクセストークンを取得できる。 f:id:sey323:20210508172155p:plain

プログラムの全体像はこちら。

import argparse
import urllib.request
from oauthlib.oauth2 import WebApplicationClient

import os

os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
SCOPE = ["innerscan"]
API_REDIRECT_URL = "https://www.healthplanet.jp/success.html"

if __name__ == "__main__":
    # 引数の設定
    parser = argparse.ArgumentParser()

    parser.add_argument("client_id", help="クライアントID")
    parser.add_argument("client_secret", help="クライアントシークレット")

    args = parser.parse_args()

    oauth = WebApplicationClient(args.client_id)

    # AccessTokenを発行するURLを取得
    authorization_response, headers, body = oauth.prepare_authorization_request(
        "https://www.healthplanet.jp/oauth/auth",
        redirect_url=API_REDIRECT_URL,
        scope=SCOPE,
    )
    print(authorization_response)

    print("上記のURLにアクセスし、取得したコードを入力して、Enterを押してください。")
    code = input()

    # AccessTokenを取得
    url, headers, body = oauth.prepare_token_request(
        "https://www.healthplanet.jp/oauth/token.",
        authorization_response=authorization_response + "&code=" + code,
        client_secret=args.client_secret,
    )

    req = urllib.request.Request(url, body.encode(), headers=headers)
    with urllib.request.urlopen(req) as res:
        print(oauth.parse_request_body_response(res.read()))

Apiのリクエス

取得したアクセストークンを利用し、体重と体脂肪率を取得してみる。

curl -X GET "https://www.healthplanet.jp/status/innerscan.json?${取得したアクセストークン}&data=1" -H "application/json"

結果は個人情報が含まれるので載せないが、上記のコマンドをターミナルから実行することで、体重や体脂肪率が取得できた。

終わりに

タニタの公式ドキュメントを確認していたら以下のような記述が、、、

下記項目は2020/6/29で連携を終了いたしました。
6023 : 筋肉量 (kg)
6024 : 筋肉スコア
6025 : 内臓脂肪レベル2(小数点有り、手入力含まず)
6026 : 内臓脂肪レベル(小数点無し、手入力含む)
6027 : 基礎代謝量 (kcal)
6028 : 体内年齢 (才)
6029 : 推定骨量 (kg)

体組成計で筋肉量や体内年齢といった情報を取得できても、APIでの提供は2020/6/29で終了してしまった模様。 正直ここら辺の情報が一番記録したかっただけに残念。

参考資料