notionary 0.2.25__py3-none-any.whl → 0.2.27__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/blocks/callout/callout_models.py +1 -0
- notionary/database/client.py +0 -2
- notionary/page/models.py +4 -9
- notionary/page/notion_page.py +70 -36
- {notionary-0.2.25.dist-info → notionary-0.2.27.dist-info}/METADATA +1 -1
- {notionary-0.2.25.dist-info → notionary-0.2.27.dist-info}/RECORD +8 -8
- {notionary-0.2.25.dist-info → notionary-0.2.27.dist-info}/LICENSE +0 -0
- {notionary-0.2.25.dist-info → notionary-0.2.27.dist-info}/WHEEL +0 -0
notionary/database/client.py
CHANGED
notionary/page/models.py
CHANGED
@@ -2,6 +2,8 @@ from typing import Any, Literal, Optional, Union
|
|
2
2
|
|
3
3
|
from pydantic import BaseModel, ConfigDict
|
4
4
|
|
5
|
+
from notionary.blocks.models import ParentObject
|
6
|
+
|
5
7
|
|
6
8
|
class TextContent(BaseModel):
|
7
9
|
content: str
|
@@ -241,13 +243,6 @@ class NotionCover(BaseModel):
|
|
241
243
|
external: Optional[ExternalCover] = None
|
242
244
|
|
243
245
|
|
244
|
-
# Parent types for Pydantic
|
245
|
-
class NotionParent(BaseModel):
|
246
|
-
type: str # 'database_id', 'page_id', 'workspace'
|
247
|
-
database_id: Optional[str] = None
|
248
|
-
page_id: Optional[str] = None
|
249
|
-
|
250
|
-
|
251
246
|
# User type for Pydantic
|
252
247
|
class NotionUser(BaseModel):
|
253
248
|
object: str # 'user'
|
@@ -274,7 +269,7 @@ class NotionDatabaseResponse(BaseModel):
|
|
274
269
|
properties: dict[
|
275
270
|
str, Any
|
276
271
|
] # Using Any for flexibility with different property schemas
|
277
|
-
parent:
|
272
|
+
parent: ParentObject
|
278
273
|
url: str
|
279
274
|
public_url: Optional[str] = None
|
280
275
|
archived: bool
|
@@ -290,7 +285,7 @@ class NotionPageResponse(BaseModel):
|
|
290
285
|
last_edited_by: NotionUser
|
291
286
|
cover: Optional[NotionCover] = None
|
292
287
|
icon: Optional[Icon] = None
|
293
|
-
parent:
|
288
|
+
parent: ParentObject
|
294
289
|
archived: bool
|
295
290
|
in_trash: bool
|
296
291
|
properties: dict[str, Any]
|
notionary/page/notion_page.py
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
from ast import Dict
|
3
4
|
import asyncio
|
4
5
|
import random
|
5
6
|
from typing import TYPE_CHECKING, Any, Callable, Optional, Union
|
6
7
|
|
8
|
+
from yaml import Token
|
9
|
+
|
7
10
|
from notionary.blocks.client import NotionBlockClient
|
8
11
|
from notionary.comments import CommentClient, Comment
|
9
12
|
from notionary.blocks.syntax_prompt_builder import SyntaxPromptBuilder
|
10
|
-
from notionary.blocks.models import DatabaseParent
|
13
|
+
from notionary.blocks.models import DatabaseParent, ParentObject
|
11
14
|
from notionary.blocks.registry.block_registry import BlockRegistry
|
12
15
|
from notionary.database.client import NotionDatabaseClient
|
13
16
|
from notionary.file_upload.client import NotionFileUploadClient
|
@@ -43,6 +46,7 @@ class NotionPage(LoggingMixin):
|
|
43
46
|
archived: bool,
|
44
47
|
in_trash: bool,
|
45
48
|
emoji_icon: Optional[str] = None,
|
49
|
+
external_icon_url: Optional[str] = None,
|
46
50
|
properties: Optional[dict[str, Any]] = None,
|
47
51
|
parent_database: Optional[NotionDatabase] = None,
|
48
52
|
token: Optional[str] = None,
|
@@ -56,11 +60,13 @@ class NotionPage(LoggingMixin):
|
|
56
60
|
self._is_archived = archived
|
57
61
|
self._is_in_trash = in_trash
|
58
62
|
self._emoji_icon = emoji_icon
|
63
|
+
self._external_icon_url = external_icon_url
|
59
64
|
self._properties = properties
|
60
65
|
self._parent_database = parent_database
|
61
66
|
|
62
67
|
self._client = NotionPageClient(token=token)
|
63
68
|
self._block_client = NotionBlockClient(token=token)
|
69
|
+
self._database_client = NotionDatabaseClient(token=token)
|
64
70
|
self._comment_client = CommentClient(token=token)
|
65
71
|
self._page_data = None
|
66
72
|
|
@@ -188,6 +194,13 @@ class NotionPage(LoggingMixin):
|
|
188
194
|
"""
|
189
195
|
return self._url
|
190
196
|
|
197
|
+
@property
|
198
|
+
def external_icon_url(self) -> Optional[str]:
|
199
|
+
"""
|
200
|
+
Get the icon of the page.
|
201
|
+
"""
|
202
|
+
return self._external_icon_url
|
203
|
+
|
191
204
|
@property
|
192
205
|
def emoji_icon(self) -> Optional[str]:
|
193
206
|
"""
|
@@ -341,12 +354,32 @@ class NotionPage(LoggingMixin):
|
|
341
354
|
)
|
342
355
|
|
343
356
|
self._emoji = page_response.icon.emoji
|
357
|
+
self._external_icon_url = None
|
344
358
|
return page_response.icon.emoji
|
345
359
|
except Exception as e:
|
346
360
|
|
347
361
|
self.logger.error(f"Error updating page emoji: {str(e)}")
|
348
362
|
return None
|
349
363
|
|
364
|
+
async def set_external_icon(self, url: str) -> Optional[str]:
|
365
|
+
"""
|
366
|
+
Sets the page icon to an external image.
|
367
|
+
"""
|
368
|
+
try:
|
369
|
+
icon = {"type": "external", "external": {"url": url}}
|
370
|
+
page_response = await self._client.patch_page(
|
371
|
+
page_id=self._page_id, data={"icon": icon}
|
372
|
+
)
|
373
|
+
|
374
|
+
self._icon = url
|
375
|
+
self._emoji = None
|
376
|
+
self.logger.info(f"Successfully updated page external icon to: {url}")
|
377
|
+
return page_response.icon.external.url
|
378
|
+
|
379
|
+
except Exception as e:
|
380
|
+
self.logger.error(f"Error updating page external icon: {str(e)}")
|
381
|
+
return None
|
382
|
+
|
350
383
|
async def create_child_database(self, title: str) -> NotionDatabase:
|
351
384
|
from notionary import NotionDatabase
|
352
385
|
|
@@ -433,30 +466,20 @@ class NotionPage(LoggingMixin):
|
|
433
466
|
"""
|
434
467
|
Get the value of a specific property.
|
435
468
|
"""
|
436
|
-
if not self.
|
437
|
-
return None
|
438
|
-
|
439
|
-
database_property_schema = self._parent_database.properties.get(property_name)
|
440
|
-
|
441
|
-
if not database_property_schema:
|
469
|
+
if property_name not in self._properties:
|
442
470
|
self.logger.warning(
|
443
|
-
"Property '%s' not found in
|
471
|
+
"Property '%s' not found in page properties", property_name
|
444
472
|
)
|
445
473
|
return None
|
446
474
|
|
447
|
-
|
475
|
+
property_schema: dict = self._properties.get(property_name)
|
476
|
+
|
477
|
+
property_type = property_schema.get("type")
|
448
478
|
|
449
479
|
if property_type == "relation":
|
450
480
|
return await self._get_relation_property_values_by_name(property_name)
|
451
481
|
|
452
|
-
|
453
|
-
self.logger.warning(
|
454
|
-
"Property '%s' not found in page properties", property_name
|
455
|
-
)
|
456
|
-
return None
|
457
|
-
|
458
|
-
property_data = self._properties.get(property_name)
|
459
|
-
return extract_property_value(property_data)
|
482
|
+
return extract_property_value(property_schema)
|
460
483
|
|
461
484
|
async def _get_relation_property_values_by_name(
|
462
485
|
self, property_name: str
|
@@ -464,7 +487,7 @@ class NotionPage(LoggingMixin):
|
|
464
487
|
"""
|
465
488
|
Retrieve the titles of all related pages for a relation property.
|
466
489
|
"""
|
467
|
-
page_property_schema = self.
|
490
|
+
page_property_schema = self._properties.get(property_name)
|
468
491
|
relation_page_ids = [
|
469
492
|
rel.get("id") for rel in page_property_schema.get("relation", [])
|
470
493
|
]
|
@@ -477,23 +500,25 @@ class NotionPage(LoggingMixin):
|
|
477
500
|
"""
|
478
501
|
Get the available options for a property (select, multi_select, status, relation).
|
479
502
|
"""
|
480
|
-
if not self.
|
481
|
-
self.logger.
|
482
|
-
"
|
483
|
-
property_name,
|
503
|
+
if property_name not in self.properties:
|
504
|
+
self.logger.warning(
|
505
|
+
"Property '%s' not found in page properties", property_name
|
484
506
|
)
|
485
507
|
return []
|
486
508
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
return
|
509
|
+
property_schema: dict = self.properties.get(property_name)
|
510
|
+
property_type = property_schema.get("type")
|
511
|
+
|
512
|
+
if property_type in ["select", "multi_select", "status"]:
|
513
|
+
options = property_schema.get(property_type, {}).get("options", [])
|
514
|
+
return [option.get("name", "") for option in options]
|
515
|
+
|
516
|
+
if property_type == "relation" and self._parent_database:
|
517
|
+
return await self._parent_database._get_relation_options(property_name)
|
518
|
+
|
519
|
+
return []
|
496
520
|
|
521
|
+
# Fix this for pages that do not ah
|
497
522
|
async def set_property_value_by_name(self, property_name: str, value: Any) -> Any:
|
498
523
|
"""
|
499
524
|
Set the value of a specific property by its name.
|
@@ -603,7 +628,8 @@ class NotionPage(LoggingMixin):
|
|
603
628
|
from notionary.database.database import NotionDatabase
|
604
629
|
|
605
630
|
title = cls._extract_title(page_response)
|
606
|
-
|
631
|
+
emoji_icon = cls._extract_page_emoji_icon(page_response)
|
632
|
+
external_icon_url = cls._extract_external_icon_url(page_response)
|
607
633
|
parent_database_id = cls._extract_parent_database_id(page_response)
|
608
634
|
|
609
635
|
parent_database = (
|
@@ -616,7 +642,8 @@ class NotionPage(LoggingMixin):
|
|
616
642
|
page_id=page_response.id,
|
617
643
|
title=title,
|
618
644
|
url=page_response.url,
|
619
|
-
emoji_icon=
|
645
|
+
emoji_icon=emoji_icon,
|
646
|
+
external_icon_url=external_icon_url,
|
620
647
|
archived=page_response.archived,
|
621
648
|
in_trash=page_response.in_trash,
|
622
649
|
properties=page_response.properties,
|
@@ -653,15 +680,22 @@ class NotionPage(LoggingMixin):
|
|
653
680
|
return ""
|
654
681
|
|
655
682
|
@staticmethod
|
656
|
-
def
|
657
|
-
"""Extract
|
683
|
+
def _extract_page_emoji_icon(page_response: NotionPageResponse) -> Optional[str]:
|
684
|
+
"""Extract external icon URL from page response."""
|
658
685
|
if not page_response.icon:
|
659
686
|
return None
|
660
687
|
|
661
688
|
if page_response.icon.type == "emoji":
|
662
689
|
return page_response.icon.emoji
|
663
690
|
|
664
|
-
|
691
|
+
@staticmethod
|
692
|
+
def _extract_external_icon_url(page_response: NotionPageResponse) -> Optional[str]:
|
693
|
+
"""Extract emoji from database response."""
|
694
|
+
if not page_response.icon:
|
695
|
+
return None
|
696
|
+
|
697
|
+
if page_response.icon.type == "external":
|
698
|
+
return page_response.icon.external.url
|
665
699
|
|
666
700
|
@staticmethod
|
667
701
|
def _extract_parent_database_id(page_response: NotionPageResponse) -> Optional[str]:
|
@@ -22,7 +22,7 @@ notionary/blocks/bulleted_list/bulleted_list_models.py,sha256=QN21PIwAP7MQoIjZeU
|
|
22
22
|
notionary/blocks/callout/__init__.py,sha256=17rdvOF5W1aPxkp-pk13rLgkx6pIciCsub3ncAv_zXk,363
|
23
23
|
notionary/blocks/callout/callout_element.py,sha256=6Ss1jv1cqAM4GuNGvuy7dCFjpp-dLavf-wXevn3IEmw,3575
|
24
24
|
notionary/blocks/callout/callout_markdown_node.py,sha256=2zZNMwg8uiGBqaMOUVOTlIK8kiq20IQ0Ylv7ZFUm-bc,602
|
25
|
-
notionary/blocks/callout/callout_models.py,sha256=
|
25
|
+
notionary/blocks/callout/callout_models.py,sha256=g_xU7oiRRseoSO86dqHPIiwoseGvvnl3jsPZbBMT-mE,865
|
26
26
|
notionary/blocks/child_database/__init__.py,sha256=FzjjHOS9Je2oXuxLK9S9Oq56-EDEZRTJBfDzkacFpY0,368
|
27
27
|
notionary/blocks/child_database/child_database_element.py,sha256=1pxtoB_XTIWorYp984TpsPMZy8A5IdQ15nJALyzme-c,2279
|
28
28
|
notionary/blocks/child_database/child_database_models.py,sha256=SP6S9tKTetKNdCkYY3QCxeXd2lq1DyfdNvDhKlhD22Q,264
|
@@ -123,7 +123,7 @@ notionary/comments/__init__.py,sha256=G0OWsaN2VgbykvhLlNSweL_f0bl16j9NpidH2UNbFc
|
|
123
123
|
notionary/comments/client.py,sha256=vWjgPFk_TPY7peq10aJc7WTG-b0q6Fn8qirAlzlqLls,7311
|
124
124
|
notionary/comments/models.py,sha256=O2-yg-0Xrs8xrzLUa4793FlyNn3HbTRsv4dqaskI6ps,3409
|
125
125
|
notionary/database/__init__.py,sha256=4tdML0fBzkOCpiWT6q-L--5NELFLbTPD0IUA_E8yZno,155
|
126
|
-
notionary/database/client.py,sha256=
|
126
|
+
notionary/database/client.py,sha256=NQWUcfMLAYsnTefFgOjgOHMYN7rn_IRBrsKPUlUY0c8,5361
|
127
127
|
notionary/database/database.py,sha256=sdo830KVInR4enaEaeMHaPadNfYnPLy5R3OW2f74w28,16558
|
128
128
|
notionary/database/database_filter_builder.py,sha256=YIkdghD5VbdwLJISMRiJ0WIJTm8jcDIL22yrvZau4sA,5950
|
129
129
|
notionary/database/database_provider.py,sha256=HB-hZ9pMjronLJS8w_b1GiQ-Ecz1uJbrWpnePL67BCA,8956
|
@@ -137,8 +137,8 @@ notionary/file_upload/models.py,sha256=bSNgw5WzkOuotyalqkkcVC_Ue6YRHR-CSJV7nZRV_
|
|
137
137
|
notionary/file_upload/notion_file_upload.py,sha256=vOEEh8g8Sj4JedrK9e-NYjJ0HXH3iGdM5N74kkVXVZQ,13221
|
138
138
|
notionary/page/client.py,sha256=IOsjWOsmODxOq-7OF0y-gcuC2HUbMIT0SvJZHrH9weQ,4520
|
139
139
|
notionary/page/markdown_whitespace_processor.py,sha256=SbWLL6bdeTGds_khDNX2mQe00lGYUFvH6PX8_xpNvBA,4634
|
140
|
-
notionary/page/models.py,sha256=
|
141
|
-
notionary/page/notion_page.py,sha256=
|
140
|
+
notionary/page/models.py,sha256=zk9QOgCDzVfYfT1Gp2bL1_Bw-QUyfWxwTTIPzIayQ7g,6945
|
141
|
+
notionary/page/notion_page.py,sha256=_Hj0U9gl3laRKs3l1Cd8tBODXZrHYxrK2Z5gw0O0Fvo,25146
|
142
142
|
notionary/page/page_content_deleting_service.py,sha256=G3im6VotG1tgI-SaqoQR-gSnOloF6CEnft1qxLps4as,4546
|
143
143
|
notionary/page/page_content_writer.py,sha256=t8N7yfW--ac7szvDmTdecFEfcF5Nz95vyCQ-lpYcOUw,3046
|
144
144
|
notionary/page/page_context.py,sha256=27vrTRZP7NsaS4dEp4pBNR30Re2hh00qKlL3xt4YtpI,1773
|
@@ -196,7 +196,7 @@ notionary/util/page_id_utils.py,sha256=AA00kRO-g3Cc50tf_XW_tb5RBuPKLuBxRa0D8LYhL
|
|
196
196
|
notionary/util/singleton.py,sha256=CKAvykndwPRZsA3n3MAY_XdCR59MBjjKP0vtm2BcvF0,428
|
197
197
|
notionary/util/singleton_metaclass.py,sha256=DMvrh0IbAV8nIG1oX-2Yz57Uk1YHB647DNxoI3pAT3s,809
|
198
198
|
notionary/workspace.py,sha256=QP4WcOIdQnlVr4M7hpGaFT-Fori_QRhsV-SBC2lnwTU,3809
|
199
|
-
notionary-0.2.
|
200
|
-
notionary-0.2.
|
201
|
-
notionary-0.2.
|
202
|
-
notionary-0.2.
|
199
|
+
notionary-0.2.27.dist-info/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
|
200
|
+
notionary-0.2.27.dist-info/METADATA,sha256=NabOWlvkZwSL3tGqEiC1DGDd-cWAUNPJaT6hdFH3KAo,9143
|
201
|
+
notionary-0.2.27.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
202
|
+
notionary-0.2.27.dist-info/RECORD,,
|
File without changes
|
File without changes
|