PythonでData APIにアクセスする

  • 投稿日:
  • by
  • カテゴリ:

この記事はMovable Type Advent Calendar 2018の13日目です。

Movable TypeのData APIでは、HTTPプロトコルを扱うことができるプログラム言語であれば、どの言語でもアクセスすることができます。
これまでにいくつかのプログラム言語でData APIにアクセスしたことがありますが、今回はPythonを試してみました。

Pythonは、機械学習のライブラリが充実していて、このところ脚光を浴びています。
また、Raspberry PIで電子工作する際にも、Pythonでプログラムを書くことが多いです。
これらのことから、PythonでData APIにアクセスすることができれば、メリットがあると考えます。

1.利用するライブラリ

Pythonでは標準で様々なライブラリがあり、それらを利用することで、様々なプログラムを組むことができます。
Data APIでアクセスする場合、HTTPプロトコルとJSONを扱いますが、これらに対応するライブラリもあります。
HTTPプロトコルは「urllib.request」、JSONは「json」というライブラリを使います。
また、URLのパースなどで「urllib.parse」というライブラリも使います。

2.コンテンツデータの取得

簡単な例として、Movable Type 7のコンテンツデータを取得するプログラムを書いてみました。
以下のような状況を想定しています。

  • IDが1番のサイトにコンテンツタイプを作成していて、そのIDは2番
  • コンテンツタイプに、「タイトル」という名前のコンテンツフィールドが存在する
  • 取得したコンテンツデータの「タイトル」フィールドの値を表示
import urllib.request, json

url = "https://path-to-mt/mt-data-api.cgi/v4/sites/1/contentTypes/2/data"
with urllib.request.urlopen(url) as res:
    html = res.read().decode("utf-8")
    j = json.loads(html)
    contents = j["items"]
    for content in contents:
         data = content["data"]
         for d in data:
             if d["label"] == "タイトル":
                 print(d["data"])

3.コンテンツデータの作成

もう1つの例として、コンテンツデータを作成するプログラムを書いてみました。
以下のような状況を想定しています。

  • 認証する際のユーザー名とパスワードは、それぞれsample_user/sample_pass
  • IDが1番のサイトにコンテンツタイプを作成していて、そのIDは2番
  • コンテンツタイプに、IDが3番のコンテンツフィールドがある
  • コンテンツデータを作成し、識別子を「test_label」、IDが3番のコンテンツフィールドの値を「test_text」にし、公開状態を公開にする
import urllib.request, urllib.parse, json

url = "http://path-to-mt/mt-data-api.cgi/v4/authentication"
data = {
    "username": "sample_user",
    "password": "sample_pass",
    "clientId": "test"
}
data = urllib.parse.urlencode(data).encode("utf-8")
with urllib.request.urlopen(url, data=data) as res:
    html = res.read().decode("utf-8")
    jsn = json.loads(html)
    accessToken = jsn["accessToken"]

url = "http://path-to-mt/mt-data-api.cgi/v4/sites/1/contentTypes/2/data"
req = urllib.request.Request(url)
req.add_header("X-MT-Authorization", "MTAuth accessToken=" + accessToken)
content = {
    "label": "test_label",
    "status": "publish",
    "data": [
        {
            "id": "3",
            "data": "test_text"
        }
    ]
}
j = json.dumps(content, separators=(',', ':'))
data = { "content_data": j }
data = urllib.parse.urlencode(data).encode("utf-8")
with urllib.request.urlopen(req, data = data) as res:
    html = res.read().decode("utf-8")
    jsn = json.loads(html)
    if ("error" in jsn):
        print("create content data error")