Skip to content

Commit cd07c1f

Browse files
authored
Update to notion api (#4)
* UPDATE: use notion-sdk-py instead of notion client
1 parent 2dbbc9c commit cd07c1f

11 files changed

+342
-356
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,5 @@ dmypy.json
129129
.pyre/
130130
.idea/
131131
graph_view.html
132+
run_local.sh
133+
.vscode

Pipfile

-13
This file was deleted.

Pipfile.lock

-204
This file was deleted.

README.md

+43-15
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,64 @@
1+
![](images/snap.png)
2+
13
# Notion Graph View
24

35
![](https://img.shields.io/github/pipenv/locked/python-version/stevedsun/notion-graph-view)
46

5-
Export [Notion](https://notion.so) pages to a Roam Research like graph view.
7+
Export [Notion](https://notion.so) pages to a Roam-Research like graph view.
8+
9+
## Usage
610

7-
![](https://tva1.sinaimg.cn/large/008eGmZEly1gnhdionmecj30yf0u0115.jpg)
11+
### Environment
812

9-
## How to use it
13+
- Python 3.7 or later (3.9 is recommended)
1014

11-
Install dependencies with `pipenv` or `pip`:
15+
### Install
1216

1317
```shell
1418
pip install -r requirements.txt
15-
# or
16-
pipenv install
1719
```
1820

19-
Login notion.so and get `token_v2` from browser ([How?](https://www.redgregory.com/notion/2020/6/15/9zuzav95gwzwewdu1dspweqbv481s5)). Paste it to `config.py`>`my_token_v2`.
21+
### Setup Notion API
22+
23+
1. Create a [notion internal integration](https://www.notion.so/my-integrations) and generate an `Internal Integration Token`. [Learn more about authorization](https://developers.notion.com/docs/authorization)
24+
2. Open one notion page on browser and share it to your integration.
25+
3. Find your base `Page ID` from browser url, for example:
26+
> if this page url is like: https://www.notion.so/yourName/PageTitle-8a4b5ff100d648fb8d39d4bfa756ff3f
27+
> the `8a4b5ff100da48fb8d39d4bfa756ff3f` is the `Page ID`
28+
4. Paste `Internal Integration Token` and `Page ID` to `config.py`:
29+
30+
```python
31+
NOTION_TOKEN = "secret_TBqfsxyH1slTpaignyZqQnDAAAn0MaeDEc2l96cdubD"
32+
PAGE_ID = "8a4b5ff100d648fb8d39d4bfa756ff3f"
33+
```
2034

21-
Paste the page url which your want to analyse into `config.py`>`my_url`.
35+
> On Linux, you can export these two environment varibles instead.
2236
23-
Then run:
37+
## Run
2438

2539
```shell
2640
python main.py
2741
```
2842

29-
Finally `graph_view.html` will be generated at the current path, open it with any browser.
43+
Finally `graph_view.html` would be generated at the project path, open it with any browser. (make sure `/lib` and `graph_view.html` in the same folder)
3044

31-
## Todo
45+
## Block link support
3246

33-
- [x] Read Notion pages, export to graph view image
34-
- [ ] Upgrade python version
35-
- [ ] Replace notion-client by notion-sdk-py
36-
- [ ] Use lightweight renderer solution
47+
| | database | page |
48+
| ------------------ | -------- | ---- |
49+
| paragraph | ✔️ | ✔️ |
50+
| bulleted_list_item | ✔️ | ✔️ |
51+
| numbered_list_item | ✔️ | ✔️ |
52+
| to_do | ✔️ | ✔️ |
53+
| toggle | ✔️ | ✔️ |
54+
| child_page | ✔️ | ✔️ |
55+
| child_database | ✔️ | ✔️ |
56+
| embed | | |
57+
| callout | | |
58+
| quote | | |
59+
| column | | |
60+
| column_list | | |
61+
| synced_block | | |
62+
| link_to_page | | |
63+
| table | ✔️ | ✔️ |
64+
| table_row | | |

config.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,15 @@
1-
my_token_v2 = "{your_token_v2}"
2-
my_url = "{root_page_url}"
1+
import os
2+
from notion_client import Client
3+
4+
5+
# Paste your NOTION token (e.g. secret_balabalabalabala) and page id (e.g. 43a57ade6650460b980e96fde16b03f1) in "" below.
6+
NOTION_TOKEN = ""
7+
PAGE_ID = ""
8+
9+
if not NOTION_TOKEN:
10+
NOTION_TOKEN = os.getenv("NOTION_TOKEN")
11+
12+
if not PAGE_ID:
13+
PAGE_ID = os.getenv("PAGE_ID")
14+
15+
notion = Client(auth=NOTION_TOKEN)

graph.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class Graph:
2+
def __init__(self):
3+
self.nodes = []
4+
self.edges = []
5+
self.parsed_block_ids = set()
6+
7+
def has_node_parsed(self, block):
8+
return block.id in self.parsed_block_ids and block.title != '<block>'
9+
10+
def add_node(self, block):
11+
if self.has_node_parsed(block):
12+
return
13+
14+
page_block_id = ''
15+
if block.parent_id:
16+
# for text block
17+
page_block_id = block.parent_id
18+
else:
19+
# for page and database block
20+
page_block_id = block.id
21+
if block.title != '<block>':
22+
self.nodes.append(
23+
dict(id=page_block_id, label=block.title, size=2))
24+
25+
for child_id in block.children_ids:
26+
self.edges.append(dict({"from": page_block_id, "to": child_id}))
27+
28+
for linked_block in block.linked_blocks:
29+
linked_id = linked_block['id']
30+
self.edges.append(dict({"from": page_block_id, "to": linked_id}))
31+
32+
self.parsed_block_ids.add(block.id)
33+
34+
def get_graph(self) -> dict[str, list]:
35+
return dict(nodes=self.nodes, edges=self.edges)
36+
37+
38+
my_graph = Graph()

images/snap.png

168 KB
Loading

main.py

+8-20
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,14 @@
1-
import os
2-
from notion.client import NotionClient
3-
4-
from config import *
5-
from parser import Parser
1+
from graph import my_graph
2+
from parser import BlockParser
63
from render import render
4+
from config import *
75

86

9-
def read_page(token_v2, page_url):
10-
client = NotionClient(token_v2=token_v2)
11-
base_block = client.get_block(page_url)
12-
print("Root Page:", base_block.title)
13-
bfs_block(base_block)
14-
print("Graph view generated")
15-
os.system("open graph_view.html")
16-
17-
18-
def bfs_block(block):
19-
print(block.type, block.title)
20-
parser = Parser(block)
21-
graph = parser.get_graph()
22-
render(block.title, graph)
7+
def read_page():
8+
block = notion.blocks.retrieve(PAGE_ID)
9+
BlockParser(block)
10+
render(my_graph.get_graph())
2311

2412

2513
if __name__ == '__main__':
26-
read_page(my_token_v2, my_url)
14+
read_page()

0 commit comments

Comments
 (0)