さいきんNotionを使い始めました。
Notionは、タスク、Wiki、およびデータベースを統合するマークダウンサポートを備えたメモアプリケーション及びサービス。 同社はこのアプリを、メモ作成、プロジェクト管理、タスク管理のためのオールインワンワークスペースと説明している。
いろいろと使い方を勉強している途中ですが、APIが公開されているということで、NotionのAPIをPythonから操作してみようと思います。
とりあえずは簡単な操作ということで、Notionデータベースにプロパティを指定してデータを追加してみます。
requestsを使います。 適宜pip installしておきましょう。
pip install requestsまずはAPIシークレットキーをデベロッパーサイトから入手しましょう。
こちらからアクセスできます。

Create new integrationをクリックします。

Nameに適当なサービス名を入れて、Associated workspaceでワークスペースを選択してSubmitを押します。

シークレットキーが発行されます。 後で使うのでメモ帳か何かに保存しておきましょう。

下の方にスクロールして、Internal integrationにチェックが入っていることを確認しておきます。
以上でここまでは終了です。
次にNotion上に適当なデータベースを作成しましょう。

サイドバーからAdd a pageと押すとこのような画面になります。 DATABASEからTableを選択します。

今回はToDo Listっぽい感じで試してみます。
Nameに適当に入力し、OPENを押します。

そうするとこのような画面からプロパティが編集できます。
Notionのデータベースのプロパティについて、Excelの表の列みたいなものだと思えばよいと思います。
名前とタイプを指定することができます。
このプロパティを元に表示を切り替えたり、並び替えたりできたり、といった感じです。
Tagsとなっている部分をクリックすることで編集ができます。

今回はToDo Listなのでタスクをいつまでにやるとか管理したいです。
なので、名前を日付に直して、Dateを選択します。

プロパティは追加していくことができます。
Todo Listだと完了とか未完了のステータスも管理したいです。
なので、タイトルを状態、Selectと選択していきます。

そうすると先ほど追加した日付と状態がセットされます。
日付のセルをクリックするとカレンダーが出てきて、日付を選択できます。

状態のほうはSelectなので、適宜選択肢を追加していく感じです。 とりあえず完了と未完了としましょう。

ここまででこんな感じになりました。
次にページ右上のShareをクリックします。

先ほど追加したAPI integrationを選択してInviteします。
次に右上の・・・をクリックして、Copy linkをクリックします。

このようなURLのはずです。
<https://www.notion.so/15hogef23cc94efuga64hoge36703844?v=ca16f2b68affuga9hoge8bfugaf9d3fd>
上の部分で、so/と?の間がDatabaseのidになります。
<https://www.notion.so/{15hogef23cc94efuga64hoge36703844}?v=ca16f2b68affuga9hoge8bfugaf9d3fd>
{}で囲った部分ということです。
これで準備がそろいました。
公式のAPIリファレンスを参考に簡単なものを試してみました。
リクエストURLはhttps://api.notion.com/v1/databases/{database_id}となります。
GETリクエストを送って結果を確認してみます。
import requests
from pprint import pprint
def get_request_url(end_point):
return f'<https://api.notion.com/v1/{end_point}>'
notion_api_key = 'your api secret'
databases_id = 'your database id'
headers = {"Authorization": f"Bearer {notion_api_key}",
"Content-Type": "application/json",
"Notion-Version": "2021-05-13"}
response = requests.request('GET', url=get_request_url(f'databases/{databases_id}'), headers=headers)
pprint(response.json())
>>>
{'created_time': '2021-07-01T13:59:10.814Z',
'id': 'your database id',
'last_edited_time': '2021-07-01T14:40:00.000Z',
'object': 'database',
'parent': {'type': 'workspace', 'workspace': True},
'properties': {'Name': {'id': 'title', 'title': {}, 'type': 'title'},
'日付': {'date': {}, 'id': 'qK>v', 'type': 'date'},
'状態': {'id': '[kjD',
'select': {'options': [{'color': 'pink',
'id': 'c5ffabea-ccb9-4fd5-9603-ef83ce068fae',
'name': '完了'},
{'color': 'brow
n',
'id': '82cf5f31-b926-482c-9cff-a3b942acc739',
'name': '未完了'}]},
'type': 'select'}},
'title': [{'annotations': {'bold': False,
'code': False,
'color': 'default',
'italic': False,
'strikethrough': False,
'underline': False},
'href': None,
'plain_text': 'ToDo List',
'text': {'content': 'ToDo List', 'link': None},
'type': 'text'}]}
それっぽいデータが返ってきました。
propertiesの部分に先ほど設定した日付とか状態という値が入っています。
次にデータを追加してみましょう。
リクエストURLはhttps://api.notion.com/v1/pages/となります。
json形式でデータを送る必要があるので、jsonをimportしておきましょう。
import json
...省略
body = {
"parent": {
"database_id": databases_id},
"properties": {
"Name": {"title": [
{"text": {"content": "POST メソッド"}}
]
}
}}
response = requests.request('POST', url=get_request_url('pages'), headers=headers, data=json.dumps(body))
pprint(response.json())
>>>
{'archived': False,
'created_time': '2021-07-01T15:44:13.837Z',
'id': 'bea3c0e2-f650-453e-b0fc-f0bec72d9811',
'last_edited_time': '2021-07-01T15:44:13.837Z',
'object': 'page',
'parent': {'database_id': 'your database id',
'type': 'database_id'},
'properties': {'Name': {'id': 'title',
'title': [{'annotations': {'bold': False,
'code': False,
'color': 'default',
'italic': False,
'strikethrough': False,
'underline': False},
'href': None,
'plain_text': 'POST メソッド',
'text': {'content': 'POST メソッド',
'link': None},
'type': 'text'}],
'type': 'title'}}}
想像はしていたのですが、階層が深いです。
一応は下の写真のように追加ができました。

日付や状態を指定して加える場合は以下のようにします。
body = {
"parent": {
"database_id": databases_id},
"properties": {
"Name": {"title": [
{"text": {"content": "日付と状態"}}
]
},
"日付": {
"date": {"start": datetime.datetime(year=2021, month=7, day=7).isoformat()}
},
"状態": {"select": {"name": "完了"}}
}}
response = requests.request('POST', url=get_request_url('pages'), headers=headers, data=json.dumps(body))

選択肢にない状態を加えると、新たに生成されます。 階層が深くなってきたので変数を使います。
多少、見やすくなります。
property_name = {"title": [{"text": {"content": "選択肢を追加"}}]}
property_date = {"date": {"start": datetime.datetime(year=2021, month=7, day=7).isoformat()}}
property_select = {"select": {"name": "新しい選択肢"}}
body = {
"parent": {
"database_id": databases_id},
"properties": {
"Name": property_name,
"日付": property_date,
"状態": property_select
}}
このように追加されます。
