-
-
Notifications
You must be signed in to change notification settings - Fork 150
/
Copy pathhelpers.py
125 lines (89 loc) · 4.2 KB
/
helpers.py
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""Utility functions for notion-sdk-py."""
from typing import Any, AsyncGenerator, Awaitable, Callable, Dict, Generator, List
from urllib.parse import urlparse
from uuid import UUID
def pick(base: Dict[Any, Any], *keys: str) -> Dict[Any, Any]:
"""Return a dict composed of key value pairs for keys passed as args."""
result = {}
for key in keys:
if key not in base:
continue
value = base.get(key)
if value is None and key == "start_cursor":
continue
result[key] = value
return result
def get_url(object_id: str) -> str:
"""Return the URL for the object with the given id."""
return f"https://notion.so/{UUID(object_id).hex}"
def get_id(url: str) -> str:
"""Return the id of the object behind the given URL."""
parsed = urlparse(url)
if parsed.netloc not in ("notion.so", "www.notion.so"):
raise ValueError("Not a valid Notion URL.")
path = parsed.path
if len(path) < 32:
raise ValueError("The path in the URL seems to be incorrect.")
raw_id = path[-32:]
return str(UUID(raw_id))
def iterate_paginated_api(
function: Callable[..., Any], **kwargs: Any
) -> Generator[Any, None, None]:
"""Return an iterator over the results of any paginated Notion API."""
next_cursor = kwargs.pop("start_cursor", None)
while True:
response = function(**kwargs, start_cursor=next_cursor)
for result in response.get("results"):
yield result
next_cursor = response.get("next_cursor")
if not response.get("has_more") or not next_cursor:
return
def collect_paginated_api(function: Callable[..., Any], **kwargs: Any) -> List[Any]:
"""Collect all the results of paginating an API into a list."""
return [result for result in iterate_paginated_api(function, **kwargs)]
async def async_iterate_paginated_api(
function: Callable[..., Awaitable[Any]], **kwargs: Any
) -> AsyncGenerator[Any, None]:
"""Return an async iterator over the results of any paginated Notion API."""
next_cursor = kwargs.pop("start_cursor", None)
while True:
response = await function(**kwargs, start_cursor=next_cursor)
for result in response.get("results"):
yield result
next_cursor = response.get("next_cursor")
if (not response["has_more"]) | (next_cursor is None):
return
async def async_collect_paginated_api(
function: Callable[..., Awaitable[Any]], **kwargs: Any
) -> List[Any]:
"""Collect asynchronously all the results of paginating an API into a list."""
return [result async for result in async_iterate_paginated_api(function, **kwargs)]
def is_full_block(response: Dict[Any, Any]) -> bool:
"""Return `True` if response is a full block."""
return response.get("object") == "block" and "type" in response
def is_full_page(response: Dict[Any, Any]) -> bool:
"""Return `True` if response is a full page."""
return response.get("object") == "page" and "url" in response
def is_full_database(response: Dict[Any, Any]) -> bool:
"""Return `True` if response is a full database."""
return response.get("object") == "database" and "title" in response
def is_full_page_or_database(response: Dict[Any, Any]) -> bool:
"""Return `True` if `response` is a full database or a full page."""
if response.get("object") == "database":
return is_full_database(response)
return is_full_page(response)
def is_full_user(response: Dict[Any, Any]) -> bool:
"""Return `True` if response is a full user."""
return "type" in response
def is_full_comment(response: Dict[Any, Any]) -> bool:
"""Return `True` if response is a full comment."""
return "type" in response
def is_text_rich_text_item_response(rich_text: Dict[Any, Any]) -> bool:
"""Return `True` if `rich_text` is a text."""
return rich_text.get("type") == "text"
def is_equation_rich_text_item_response(rich_text: Dict[Any, Any]) -> bool:
"""Return `True` if `rich_text` is an equation."""
return rich_text.get("type") == "equation"
def is_mention_rich_text_item_response(rich_text: Dict[Any, Any]) -> bool:
"""Return `True` if `rich_text` is a mention."""
return rich_text.get("type") == "mention"