notionary 0.2.12__py3-none-any.whl → 0.2.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- notionary/__init__.py +3 -20
- notionary/{notion_client.py → base_notion_client.py} +92 -98
- notionary/blocks/__init__.py +61 -0
- notionary/{elements → blocks}/audio_element.py +6 -4
- notionary/{elements → blocks}/bookmark_element.py +3 -6
- notionary/{elements → blocks}/bulleted_list_element.py +5 -7
- notionary/{elements → blocks}/callout_element.py +5 -8
- notionary/{elements → blocks}/code_block_element.py +4 -6
- notionary/{elements → blocks}/column_element.py +3 -6
- notionary/{elements → blocks}/divider_element.py +3 -6
- notionary/{elements → blocks}/embed_element.py +4 -6
- notionary/{elements → blocks}/heading_element.py +5 -9
- notionary/{elements → blocks}/image_element.py +4 -6
- notionary/{elements → blocks}/mention_element.py +3 -7
- notionary/blocks/notion_block_client.py +26 -0
- notionary/blocks/notion_block_element.py +34 -0
- notionary/{elements → blocks}/numbered_list_element.py +4 -7
- notionary/{elements → blocks}/paragraph_element.py +4 -7
- notionary/{prompting/element_prompt_content.py → blocks/prompts/element_prompt_builder.py} +1 -40
- notionary/blocks/prompts/element_prompt_content.py +41 -0
- notionary/{elements → blocks}/qoute_element.py +4 -6
- notionary/{elements → blocks}/registry/block_registry.py +4 -26
- notionary/{elements → blocks}/registry/block_registry_builder.py +26 -25
- notionary/{elements → blocks}/table_element.py +6 -8
- notionary/{elements → blocks}/text_inline_formatter.py +1 -4
- notionary/{elements → blocks}/todo_element.py +6 -8
- notionary/{elements → blocks}/toggle_element.py +3 -6
- notionary/{elements → blocks}/toggleable_heading_element.py +5 -8
- notionary/{elements → blocks}/video_element.py +4 -6
- notionary/cli/main.py +245 -53
- notionary/cli/onboarding.py +117 -0
- notionary/database/__init__.py +0 -0
- notionary/database/client.py +132 -0
- notionary/database/database_exceptions.py +13 -0
- notionary/database/factory.py +0 -0
- notionary/database/filter_builder.py +175 -0
- notionary/database/notion_database.py +339 -128
- notionary/database/notion_database_provider.py +230 -0
- notionary/elements/__init__.py +0 -0
- notionary/models/notion_database_response.py +294 -13
- notionary/models/notion_page_response.py +9 -31
- notionary/models/search_response.py +0 -0
- notionary/page/__init__.py +0 -0
- notionary/page/client.py +110 -0
- notionary/page/content/page_content_retriever.py +5 -20
- notionary/page/content/page_content_writer.py +3 -4
- notionary/page/formatting/markdown_to_notion_converter.py +1 -3
- notionary/{prompting → page}/markdown_syntax_prompt_generator.py +1 -2
- notionary/page/notion_page.py +354 -317
- notionary/page/notion_to_markdown_converter.py +1 -4
- notionary/page/properites/property_value_extractor.py +0 -64
- notionary/page/{properites/property_formatter.py → property_formatter.py} +7 -4
- notionary/page/search_filter_builder.py +131 -0
- notionary/page/utils.py +60 -0
- notionary/util/__init__.py +12 -3
- notionary/util/factory_decorator.py +33 -0
- notionary/util/fuzzy_matcher.py +82 -0
- notionary/util/page_id_utils.py +0 -21
- notionary/util/singleton_metaclass.py +22 -0
- notionary/workspace.py +69 -0
- {notionary-0.2.12.dist-info → notionary-0.2.14.dist-info}/METADATA +4 -1
- notionary-0.2.14.dist-info/RECORD +72 -0
- notionary/database/database_discovery.py +0 -142
- notionary/database/notion_database_factory.py +0 -193
- notionary/elements/notion_block_element.py +0 -70
- notionary/exceptions/database_exceptions.py +0 -76
- notionary/exceptions/page_creation_exception.py +0 -9
- notionary/page/metadata/metadata_editor.py +0 -150
- notionary/page/metadata/notion_icon_manager.py +0 -77
- notionary/page/metadata/notion_page_cover_manager.py +0 -56
- notionary/page/notion_page_factory.py +0 -332
- notionary/page/properites/database_property_service.py +0 -302
- notionary/page/properites/page_property_manager.py +0 -152
- notionary/page/relations/notion_page_relation_manager.py +0 -350
- notionary/page/relations/notion_page_title_resolver.py +0 -104
- notionary/page/relations/page_database_relation.py +0 -68
- notionary/telemetry/__init__.py +0 -7
- notionary/telemetry/telemetry.py +0 -226
- notionary/telemetry/track_usage_decorator.py +0 -76
- notionary/util/warn_direct_constructor_usage.py +0 -54
- notionary-0.2.12.dist-info/RECORD +0 -70
- /notionary/util/{singleton.py → singleton_decorator.py} +0 -0
- {notionary-0.2.12.dist-info → notionary-0.2.14.dist-info}/WHEEL +0 -0
- {notionary-0.2.12.dist-info → notionary-0.2.14.dist-info}/entry_points.txt +0 -0
- {notionary-0.2.12.dist-info → notionary-0.2.14.dist-info}/licenses/LICENSE +0 -0
- {notionary-0.2.12.dist-info → notionary-0.2.14.dist-info}/top_level.txt +0 -0
@@ -1,350 +0,0 @@
|
|
1
|
-
import asyncio
|
2
|
-
from typing import Any, Dict, List, Optional
|
3
|
-
from notionary.models.notion_page_response import DatabaseParent, NotionPageResponse
|
4
|
-
from notionary.notion_client import NotionClient
|
5
|
-
from notionary.page.relations.notion_page_title_resolver import (
|
6
|
-
NotionPageTitleResolver,
|
7
|
-
)
|
8
|
-
from notionary.util import LoggingMixin
|
9
|
-
|
10
|
-
|
11
|
-
class NotionPageRelationManager(LoggingMixin):
|
12
|
-
"""
|
13
|
-
Manager for relation properties of a Notion page.
|
14
|
-
Manages links between pages and loads available relation options.
|
15
|
-
"""
|
16
|
-
|
17
|
-
def __init__(
|
18
|
-
self, page_id: str, client: NotionClient, database_id: Optional[str] = None
|
19
|
-
):
|
20
|
-
"""
|
21
|
-
Initializes the relation manager.
|
22
|
-
"""
|
23
|
-
self._page_id = page_id
|
24
|
-
self._client = client
|
25
|
-
self._database_id = database_id
|
26
|
-
self._page_properties = None
|
27
|
-
|
28
|
-
self._page_title_resolver = NotionPageTitleResolver(client=client)
|
29
|
-
|
30
|
-
async def get_relation_property_ids(self) -> List[str]:
|
31
|
-
"""
|
32
|
-
Returns a list of all relation property names.
|
33
|
-
|
34
|
-
Returns:
|
35
|
-
List[str]: Names of all relation properties
|
36
|
-
"""
|
37
|
-
properties = await self._get_page_properties()
|
38
|
-
|
39
|
-
return [
|
40
|
-
prop_name
|
41
|
-
for prop_name, prop_data in properties.items()
|
42
|
-
if prop_data.get("type") == "relation"
|
43
|
-
]
|
44
|
-
|
45
|
-
async def get_relation_values(self, property_name: str) -> List[str]:
|
46
|
-
"""
|
47
|
-
Returns the titles of the pages linked via a relation property.
|
48
|
-
|
49
|
-
Args:
|
50
|
-
property_name: Name of the relation property
|
51
|
-
|
52
|
-
Returns:
|
53
|
-
List[str]: List of linked page titles
|
54
|
-
"""
|
55
|
-
properties = await self._get_page_properties()
|
56
|
-
|
57
|
-
if property_name not in properties:
|
58
|
-
return []
|
59
|
-
|
60
|
-
prop_data = properties[property_name]
|
61
|
-
|
62
|
-
if prop_data.get("type") != "relation" or "relation" not in prop_data:
|
63
|
-
return []
|
64
|
-
|
65
|
-
resolver = NotionPageTitleResolver(self._client)
|
66
|
-
titles = []
|
67
|
-
|
68
|
-
for rel in prop_data["relation"]:
|
69
|
-
page_id = rel.get("id")
|
70
|
-
if not page_id:
|
71
|
-
continue
|
72
|
-
|
73
|
-
title = await resolver.get_title_by_page_id(page_id)
|
74
|
-
if not title:
|
75
|
-
continue
|
76
|
-
|
77
|
-
titles.append(title)
|
78
|
-
|
79
|
-
return titles
|
80
|
-
|
81
|
-
async def get_relation_database_id(self, property_name: str) -> Optional[str]:
|
82
|
-
"""
|
83
|
-
Returns the ID of the linked database for a relation property.
|
84
|
-
|
85
|
-
Args:
|
86
|
-
property_name: Name of the relation property
|
87
|
-
|
88
|
-
Returns:
|
89
|
-
Optional[str]: ID of the linked database or None
|
90
|
-
"""
|
91
|
-
relation_details = await self._get_relation_details(property_name)
|
92
|
-
|
93
|
-
if not relation_details:
|
94
|
-
return None
|
95
|
-
|
96
|
-
return relation_details.get("database_id")
|
97
|
-
|
98
|
-
async def get_relation_options(
|
99
|
-
self, property_name: str, limit: int = 100
|
100
|
-
) -> List[str]:
|
101
|
-
"""
|
102
|
-
Returns available title options for a relation property.
|
103
|
-
|
104
|
-
Args:
|
105
|
-
property_name: Name of the relation property
|
106
|
-
limit: Maximum number of options to return
|
107
|
-
|
108
|
-
Returns:
|
109
|
-
List[str]: List of page titles that can be used for this relation
|
110
|
-
"""
|
111
|
-
related_db_id = await self.get_relation_database_id(property_name)
|
112
|
-
|
113
|
-
if not related_db_id:
|
114
|
-
return []
|
115
|
-
|
116
|
-
try:
|
117
|
-
query_result = await self._client.post(
|
118
|
-
f"databases/{related_db_id}/query",
|
119
|
-
{
|
120
|
-
"page_size": limit,
|
121
|
-
},
|
122
|
-
)
|
123
|
-
|
124
|
-
if not query_result or "results" not in query_result:
|
125
|
-
return []
|
126
|
-
|
127
|
-
titles = []
|
128
|
-
for page in query_result["results"]:
|
129
|
-
title = self._extract_title_from_page(page)
|
130
|
-
if title:
|
131
|
-
titles.append(title)
|
132
|
-
|
133
|
-
return titles
|
134
|
-
except Exception as e:
|
135
|
-
self.logger.error("Error retrieving relation options: %s", str(e))
|
136
|
-
return []
|
137
|
-
|
138
|
-
async def set_relation_values_by_page_titles(
|
139
|
-
self, property_name: str, page_titles: List[str]
|
140
|
-
) -> List[str]:
|
141
|
-
"""
|
142
|
-
Sets relation values based on page titles, replacing any existing relations.
|
143
|
-
|
144
|
-
Args:
|
145
|
-
property_name: Name of the relation property
|
146
|
-
page_titles: List of page titles to set as relations
|
147
|
-
|
148
|
-
Returns:
|
149
|
-
List[str]: List of page titles that were successfully set as relations
|
150
|
-
"""
|
151
|
-
self.logger.info(
|
152
|
-
"Setting %d relation(s) for property '%s'",
|
153
|
-
len(page_titles),
|
154
|
-
property_name,
|
155
|
-
)
|
156
|
-
|
157
|
-
resolution_results = await asyncio.gather(
|
158
|
-
*(
|
159
|
-
self._page_title_resolver.get_page_id_by_title(title)
|
160
|
-
for title in page_titles
|
161
|
-
)
|
162
|
-
)
|
163
|
-
|
164
|
-
found_pages = []
|
165
|
-
page_ids = []
|
166
|
-
not_found_pages = []
|
167
|
-
|
168
|
-
for title, page_id in zip(page_titles, resolution_results):
|
169
|
-
if page_id:
|
170
|
-
found_pages.append(title)
|
171
|
-
page_ids.append(page_id)
|
172
|
-
self.logger.debug("Found page ID %s for title '%s'", page_id, title)
|
173
|
-
else:
|
174
|
-
not_found_pages.append(title)
|
175
|
-
self.logger.warning("No page found with title '%s'", title)
|
176
|
-
|
177
|
-
self.logger.debug("Page IDs being sent to API: %s", page_ids)
|
178
|
-
|
179
|
-
if not page_ids:
|
180
|
-
self.logger.warning(
|
181
|
-
"No valid page IDs found for any of the titles, no changes applied"
|
182
|
-
)
|
183
|
-
return []
|
184
|
-
|
185
|
-
api_response = await self._set_relations_by_page_ids(property_name, page_ids)
|
186
|
-
|
187
|
-
if not api_response:
|
188
|
-
self.logger.error(
|
189
|
-
"Failed to set relations for '%s' (API error)", property_name
|
190
|
-
)
|
191
|
-
return []
|
192
|
-
|
193
|
-
if not_found_pages:
|
194
|
-
not_found_str = "', '".join(not_found_pages)
|
195
|
-
self.logger.info(
|
196
|
-
"Set %d relation(s) for '%s', but couldn't find pages: '%s'",
|
197
|
-
len(page_ids),
|
198
|
-
property_name,
|
199
|
-
not_found_str,
|
200
|
-
)
|
201
|
-
else:
|
202
|
-
self.logger.info(
|
203
|
-
"Successfully set all %d relation(s) for '%s'",
|
204
|
-
len(page_ids),
|
205
|
-
property_name,
|
206
|
-
)
|
207
|
-
|
208
|
-
return found_pages
|
209
|
-
|
210
|
-
async def get_all_relations(self) -> Dict[str, List[str]]:
|
211
|
-
"""
|
212
|
-
Returns all relation properties and their values.
|
213
|
-
|
214
|
-
Returns:
|
215
|
-
Dict[str, List[str]]: Dictionary of property names and their values
|
216
|
-
"""
|
217
|
-
relation_properties = await self.get_relation_property_ids()
|
218
|
-
|
219
|
-
if not relation_properties:
|
220
|
-
return {}
|
221
|
-
|
222
|
-
result = {}
|
223
|
-
for prop_name in relation_properties:
|
224
|
-
result[prop_name] = await self.get_relation_values(prop_name)
|
225
|
-
|
226
|
-
return result
|
227
|
-
|
228
|
-
async def _get_relation_details(
|
229
|
-
self, property_name: str
|
230
|
-
) -> Optional[Dict[str, Any]]:
|
231
|
-
"""
|
232
|
-
Returns details about the relation property, including the linked database.
|
233
|
-
|
234
|
-
Args:
|
235
|
-
property_name: Name of the relation property
|
236
|
-
|
237
|
-
Returns:
|
238
|
-
The "relation" field of the property, or None if not found or not of type "relation".
|
239
|
-
"""
|
240
|
-
database_id = await self._ensure_database_id()
|
241
|
-
if not database_id:
|
242
|
-
return None
|
243
|
-
|
244
|
-
try:
|
245
|
-
database = await self._client.get_database(database_id)
|
246
|
-
|
247
|
-
prop_data = database.properties.get(property_name)
|
248
|
-
if not prop_data:
|
249
|
-
return None
|
250
|
-
|
251
|
-
if prop_data.get("type") != "relation":
|
252
|
-
return None
|
253
|
-
|
254
|
-
return prop_data.get("relation")
|
255
|
-
|
256
|
-
except Exception as e:
|
257
|
-
self.logger.error("Error retrieving relation details: %s", str(e))
|
258
|
-
return None
|
259
|
-
|
260
|
-
async def _get_page_properties(self, force_refresh: bool = False) -> Dict[str, Any]:
|
261
|
-
"""
|
262
|
-
Loads the properties of the page.
|
263
|
-
|
264
|
-
Args:
|
265
|
-
force_refresh: If True, a new API call will be made.
|
266
|
-
|
267
|
-
Returns:
|
268
|
-
Dict[str, Any]: The properties of the page.
|
269
|
-
"""
|
270
|
-
if self._page_properties is None or force_refresh:
|
271
|
-
page_data = await self._client.get_page(self._page_id)
|
272
|
-
if page_data:
|
273
|
-
self._page_properties = page_data.properties or {}
|
274
|
-
else:
|
275
|
-
self._page_properties = {}
|
276
|
-
|
277
|
-
return self._page_properties
|
278
|
-
|
279
|
-
async def _ensure_database_id(self) -> Optional[str]:
|
280
|
-
"""
|
281
|
-
Ensures the database_id is available. Loads it if necessary.
|
282
|
-
|
283
|
-
Returns:
|
284
|
-
Optional[str]: The database ID or None
|
285
|
-
"""
|
286
|
-
if self._database_id:
|
287
|
-
return self._database_id
|
288
|
-
|
289
|
-
page_data = await self._client.get_page(self._page_id)
|
290
|
-
|
291
|
-
if not page_data or not page_data.parent:
|
292
|
-
return None
|
293
|
-
|
294
|
-
if isinstance(page_data.parent, DatabaseParent):
|
295
|
-
self._database_id = page_data.parent.database_id
|
296
|
-
return self._database_id
|
297
|
-
|
298
|
-
return None
|
299
|
-
|
300
|
-
def _extract_title_from_page(self, page: Dict[str, Any]) -> Optional[str]:
|
301
|
-
"""
|
302
|
-
Extracts the title from a page object.
|
303
|
-
|
304
|
-
Args:
|
305
|
-
page: The page object from the Notion API
|
306
|
-
|
307
|
-
Returns:
|
308
|
-
Optional[str]: The page title or None
|
309
|
-
"""
|
310
|
-
if "properties" not in page:
|
311
|
-
return None
|
312
|
-
|
313
|
-
properties = page["properties"]
|
314
|
-
|
315
|
-
for prop_data in properties.values():
|
316
|
-
if prop_data.get("type") == "title" and "title" in prop_data:
|
317
|
-
title_parts = prop_data["title"]
|
318
|
-
return "".join(
|
319
|
-
[text_obj.get("plain_text", "") for text_obj in title_parts]
|
320
|
-
)
|
321
|
-
|
322
|
-
return None
|
323
|
-
|
324
|
-
async def _set_relations_by_page_ids(
|
325
|
-
self, property_name: str, page_ids: List[str]
|
326
|
-
) -> Optional[NotionPageResponse]:
|
327
|
-
"""
|
328
|
-
Adds one or more relations.
|
329
|
-
|
330
|
-
Args:
|
331
|
-
property_name: Name of the relation property
|
332
|
-
page_ids: List of page IDs to add
|
333
|
-
|
334
|
-
Returns:
|
335
|
-
Optional[NotionPageResponse]: API response or None on error
|
336
|
-
"""
|
337
|
-
relation_payload = {"relation": [{"id": page_id} for page_id in page_ids]}
|
338
|
-
|
339
|
-
try:
|
340
|
-
page_response: NotionPageResponse = await self._client.patch_page(
|
341
|
-
self._page_id,
|
342
|
-
{"properties": {property_name: relation_payload}},
|
343
|
-
)
|
344
|
-
|
345
|
-
self._page_properties = None
|
346
|
-
|
347
|
-
return page_response
|
348
|
-
except Exception as e:
|
349
|
-
self.logger.error("Error adding relation: %s", str(e))
|
350
|
-
return None
|
@@ -1,104 +0,0 @@
|
|
1
|
-
from typing import Optional, Dict, Any, List
|
2
|
-
from notionary.notion_client import NotionClient
|
3
|
-
from notionary.util import LoggingMixin
|
4
|
-
|
5
|
-
|
6
|
-
class NotionPageTitleResolver(LoggingMixin):
|
7
|
-
def __init__(self, client: NotionClient):
|
8
|
-
self._client = client
|
9
|
-
|
10
|
-
async def get_page_id_by_title(self, title: str) -> Optional[str]:
|
11
|
-
"""
|
12
|
-
Searches for a Notion page by its title and returns the corresponding page ID if found.
|
13
|
-
"""
|
14
|
-
try:
|
15
|
-
search_results = await self._client.post(
|
16
|
-
"search",
|
17
|
-
{"query": title, "filter": {"value": "page", "property": "object"}},
|
18
|
-
)
|
19
|
-
|
20
|
-
results = search_results.get("results", [])
|
21
|
-
|
22
|
-
if not results:
|
23
|
-
self.logger.debug(f"No page found with title '{title}'")
|
24
|
-
return None
|
25
|
-
|
26
|
-
# Durchsuche die Ergebnisse nach dem passenden Titel
|
27
|
-
for result in results:
|
28
|
-
properties = result.get("properties", {})
|
29
|
-
page_title = self._extract_page_title_from_properties(properties)
|
30
|
-
|
31
|
-
if page_title == title:
|
32
|
-
return result.get("id")
|
33
|
-
|
34
|
-
self.logger.debug(f"No matching page found with title '{title}'")
|
35
|
-
return None
|
36
|
-
|
37
|
-
except Exception as e:
|
38
|
-
self.logger.error(f"Error while searching for page '{title}': {e}")
|
39
|
-
return None
|
40
|
-
|
41
|
-
async def get_title_by_page_id(self, page_id: str) -> Optional[str]:
|
42
|
-
"""
|
43
|
-
Retrieves the title of a Notion page by its page ID.
|
44
|
-
|
45
|
-
Args:
|
46
|
-
page_id: The ID of the Notion page.
|
47
|
-
|
48
|
-
Returns:
|
49
|
-
The title of the page, or None if not found.
|
50
|
-
"""
|
51
|
-
try:
|
52
|
-
page = await self._client.get_page(page_id)
|
53
|
-
return self._extract_page_title_from_properties(page.properties)
|
54
|
-
|
55
|
-
except Exception as e:
|
56
|
-
self.logger.error(f"Error retrieving title for page ID '{page_id}': {e}")
|
57
|
-
return None
|
58
|
-
|
59
|
-
async def get_page_titles_by_ids(self, page_ids: List[str]) -> Dict[str, str]:
|
60
|
-
"""
|
61
|
-
Retrieves titles for multiple page IDs at once.
|
62
|
-
|
63
|
-
Args:
|
64
|
-
page_ids: List of page IDs to get titles for
|
65
|
-
|
66
|
-
Returns:
|
67
|
-
Dictionary mapping page IDs to their titles
|
68
|
-
"""
|
69
|
-
result = {}
|
70
|
-
for page_id in page_ids:
|
71
|
-
title = await self.get_title_by_page_id(page_id)
|
72
|
-
if title:
|
73
|
-
result[page_id] = title
|
74
|
-
return result
|
75
|
-
|
76
|
-
def _extract_page_title_from_properties(self, properties: Dict[str, Any]) -> str:
|
77
|
-
"""
|
78
|
-
Extract title from properties dictionary.
|
79
|
-
|
80
|
-
Args:
|
81
|
-
properties: The properties dictionary from a Notion page
|
82
|
-
|
83
|
-
Returns:
|
84
|
-
str: The extracted title or "Untitled" if not found
|
85
|
-
"""
|
86
|
-
try:
|
87
|
-
for prop_value in properties.values():
|
88
|
-
if not isinstance(prop_value, dict):
|
89
|
-
continue
|
90
|
-
|
91
|
-
if prop_value.get("type") != "title":
|
92
|
-
continue
|
93
|
-
|
94
|
-
title_array = prop_value.get("title", [])
|
95
|
-
if not title_array:
|
96
|
-
continue
|
97
|
-
|
98
|
-
for text_obj in title_array:
|
99
|
-
if "plain_text" in text_obj:
|
100
|
-
return text_obj["plain_text"]
|
101
|
-
except Exception as e:
|
102
|
-
self.logger.error(f"Error extracting page title from properties: {e}")
|
103
|
-
|
104
|
-
return "Untitled"
|
@@ -1,68 +0,0 @@
|
|
1
|
-
from typing import Dict, Optional, Any
|
2
|
-
from notionary.models.notion_page_response import DatabaseParent, NotionPageResponse
|
3
|
-
from notionary.notion_client import NotionClient
|
4
|
-
from notionary.util import LoggingMixin
|
5
|
-
|
6
|
-
|
7
|
-
class PageDatabaseRelation(LoggingMixin):
|
8
|
-
"""
|
9
|
-
Manages the relationship between a Notion page and its parent database.
|
10
|
-
Provides methods to access database schema and property options.
|
11
|
-
"""
|
12
|
-
|
13
|
-
def __init__(self, page_id: str, client: NotionClient):
|
14
|
-
"""
|
15
|
-
Initialize the page-database relationship handler.
|
16
|
-
|
17
|
-
Args:
|
18
|
-
page_id: ID of the Notion page
|
19
|
-
client: Instance of NotionClient
|
20
|
-
"""
|
21
|
-
self._page_id = page_id
|
22
|
-
self._client = client
|
23
|
-
self._parent_database_id = None
|
24
|
-
self._database_schema = None
|
25
|
-
self._page_data = None
|
26
|
-
|
27
|
-
async def _get_page_data(self, force_refresh=False) -> NotionPageResponse:
|
28
|
-
"""
|
29
|
-
Gets the page data and caches it for future use.
|
30
|
-
|
31
|
-
Args:
|
32
|
-
force_refresh: Whether to force a refresh of the page data
|
33
|
-
|
34
|
-
Returns:
|
35
|
-
Dict[str, Any]: The page data
|
36
|
-
"""
|
37
|
-
if self._page_data is None or force_refresh:
|
38
|
-
self._page_data = await self._client.get_page(self._page_id)
|
39
|
-
return self._page_data
|
40
|
-
|
41
|
-
async def get_parent_database_id(self) -> Optional[str]:
|
42
|
-
"""
|
43
|
-
Returns the ID of the database this page belongs to, if any.
|
44
|
-
"""
|
45
|
-
if self._parent_database_id is not None:
|
46
|
-
return self._parent_database_id
|
47
|
-
|
48
|
-
page_data = await self._get_page_data()
|
49
|
-
|
50
|
-
if not page_data:
|
51
|
-
return None
|
52
|
-
|
53
|
-
parent = page_data.parent
|
54
|
-
if isinstance(parent, DatabaseParent):
|
55
|
-
self._parent_database_id = parent.database_id
|
56
|
-
return self._parent_database_id
|
57
|
-
|
58
|
-
return None
|
59
|
-
|
60
|
-
async def is_database_page(self) -> bool:
|
61
|
-
"""
|
62
|
-
Checks if this page belongs to a database.
|
63
|
-
|
64
|
-
Returns:
|
65
|
-
bool: True if the page belongs to a database, False otherwise
|
66
|
-
"""
|
67
|
-
database_id = await self.get_parent_database_id()
|
68
|
-
return database_id is not None
|