こんにちは、みやびのです。
8月30日にTodoistのAPIのv7が廃止され、v8に移行されました。
互換性なんぞ気にしない大胆な仕様変更がされているので対応は必須です。
今回は、
・TodoistのAPIのv8の主な変更点
・Pythonのライブラリの対応状況と応急処置
の2点について書いています。
2019/10/11追記
todoist-python・pyTodoistライブラリは共にv8に対応済みです。
目次
TodoistのAPIのv8の主な変更点
今回の変更はかなり多いですが、特に影響の大きいと私が思ったものを以下に記載します。
・APIのURLを変更
・プロパティの変更
・一部コマンドの削除
ざっくりと言うと
「互換性?なにそれおいしいの?」
というレベルの仕様変更です。
しかも古いコードが廃止されるのが辛い。
変更の詳細は「公式ドキュメント」をお読みください。
APIのURLの変更
APIにPOSTするときのURLを修正が必要です。
具体的には以下の変更となります。
変更前:https://todoist.com/api/v7/*
変更後:https://api.todoist.com/sync/v8/*
地味にサブドメインになっていますね。ディレクトリ名も変わってます。
v7とURLに入っている時点で昔からそうだったのかもしれませんが、バージョンアップのたびにURLが変わってしまうのはなかなか辛いですね。
◆対応方法
基本的には、APIのURLを書き換えればOKです。
しかしURLの記述内容によってはかなり修正が面倒になりそうですね。
プロパティの変更
プロパティが新しいものに置き換わっています。しかもデータベースには新旧のプロパティデータが混在しているという心折設計。
特に影響の大きいものは「date_string、date_lang、due_date_utcプロパティが期限オブジェクト(due)に変更された」という点です。
日付関連のプロパティは使ってた人も多いと思うので影響はかなりでかいですね。
私も調整にかなり苦労しました。
◆対応方法
「旧プロパティを期限オブジェクトに変更すればOK!」
だったらよかったんですが、残念ながらv8以前に作ったオブジェクトは古いプロパティのままです。
よって古い処理は残しつつ、新しい処理を追加する必要があります。
・keyにdueがあるかチェックする
・dueがあれば新しいデータなのでdueの内容をチェックする
・dueがなければ古いデータなのでdate_string、date_lang、due_date_utcプロパティをチェックする
一部コマンドの削除
item_update_orders_indents同期コマンドなどの一部コマンドは削除されました。
削除対象のコマンドを使っている場合は当然エラーとなるので修正する必要があります。
詳しく見てはないですが、同等の機能はあるようなのでそちらに修正しましょう。
◆対応方法
新しい実装方法に修正する
Pythonのライブラリの対応状況と応急処置
todoist-python及びpyTodoistの2つはv8に対応済みです。
今後は以下の対応は不要です。
◆todoist-pythonの修正方法
自前でメソッドを作るのが手っ取り早いと思います。
sync()コマンドを修正する例です。
ライブラリのディレクトリ「lib/python3.x/site-packages/todoist/api.py」からsync()のメソッドをコピーします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | def sync(self, commands=None): """ Sends to the server the changes that were made locally, and also fetches the latest updated data from the server. """ post_data = { 'token': self.token, 'sync_token': self.sync_token, 'day_orders_timestamp': self.state['day_orders_timestamp'], 'include_notification_settings': 1, 'resource_types': json_dumps(['all']), 'commands': json_dumps(commands or []), } response = self._post('sync', data=post_data, url='') if 'temp_id_mapping' in response: for temp_id, new_id in response['temp_id_mapping'].items(): self.temp_ids[temp_id] = new_id self._replace_temp_id(temp_id, new_id) self._update_state(response) self._write_cache() return response |
ローカルの関数が必要なのでこれもコピーしてきます。
1 2 3 4 5 6 7 8 9 10 11 | def json_default(obj): if isinstance(obj, datetime): return obj.strftime('%Y-%m-%dT%H:%M:%S') elif isinstance(obj, datetime.date): return obj.strftime('%Y-%m-%d') elif isinstance(obj, datetime.time): return obj.strftime('%H:%M:%S') json_dumps = functools.partial( json.dumps, separators=',:', default=json_default) |
Postの部分を書き換えます。
1 | response = self._post('sync', data=post_data, url='https://api.todoist.com/sync/v8/') |
あとは、self及びself.apiの部分をapiに置き換えます。
まとめると以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | import todoist import os from datetime import datetime, timedelta import json import functools def json_default(obj): if isinstance(obj, datetime.datetime): return obj.strftime('%Y-%m-%dT%H:%M:%S') elif isinstance(obj, datetime.date): return obj.strftime('%Y-%m-%d') elif isinstance(obj, datetime.time): return obj.strftime('%H:%M:%S') json_dumps = functools.partial( json.dumps, separators=',:', default=json_default) def sync(api, commands=None): post_data = { 'token': api.token, 'sync_token': api.sync_token, 'full_sync': True, 'day_orders_timestamp': api.state['day_orders_timestamp'], 'include_notification_settings': 1, 'resource_types': json_dumps(['all']), 'commands': json_dumps(commands or []), } response = api._post('sync', data=post_data, url='https://api.todoist.com/sync/v8/') if 'temp_id_mapping' in response: for temp_id, new_id in response['temp_id_mapping'].items(): api.temp_ids[temp_id] = new_id api._replace_temp_id(temp_id, new_id) api._update_state(response) api._write_cache() return response # APIの設定 api_token = os.environ['TODOIST_API_TOKEN'] api = todoist.TodoistAPI(api_token) # 同期する sync(api) print(api['items']) |
終わりに
8月30日にTodoistのAPIのv7が廃止され、v8に移行され、大幅な変更が行われました。
互換性がない上に古いバージョンが廃止されてしまうのはAPIを使う側としてはなかなか辛いですね。
私は切り替えを全く知らなかったので、
「あれ?急に使えなくなったぞ?」
という感じでした(笑)
おそらくv9でも大幅な変更があると思います。β版は早期に公開されるようなので、切り替わる前に対応するのが大事ですね。
関連記事
「todoist-python」ライブラリでタスクを取得する方法
TodoistのAPIで今日の予定を確認する〜PythonでTodoistを管理〜
「PyTodoist」ライブラリでタスクを取得する方法
Todoistまとめ>>Todoist活用方法まとめ