notionary 0.4.0__py3-none-any.whl → 0.4.2__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 +44 -1
- notionary/blocks/client.py +37 -11
- notionary/blocks/rich_text/markdown_rich_text_converter.py +49 -15
- notionary/blocks/rich_text/models.py +13 -4
- notionary/blocks/rich_text/name_id_resolver/data_source.py +9 -3
- notionary/blocks/rich_text/name_id_resolver/person.py +6 -2
- notionary/blocks/rich_text/rich_text_markdown_converter.py +10 -3
- notionary/blocks/schemas.py +2 -1
- notionary/comments/client.py +19 -6
- notionary/comments/factory.py +10 -3
- notionary/comments/schemas.py +9 -3
- notionary/comments/service.py +12 -4
- notionary/data_source/http/data_source_instance_client.py +59 -17
- notionary/data_source/properties/schemas.py +30 -10
- notionary/data_source/query/builder.py +67 -18
- notionary/data_source/query/resolver.py +16 -5
- notionary/data_source/query/schema.py +24 -6
- notionary/data_source/query/validator.py +18 -6
- notionary/data_source/schema/registry.py +31 -12
- notionary/data_source/schema/service.py +66 -20
- notionary/data_source/service.py +74 -23
- notionary/database/client.py +27 -9
- notionary/database/database_metadata_update_client.py +12 -4
- notionary/database/service.py +11 -4
- notionary/exceptions/__init__.py +15 -3
- notionary/exceptions/block_parsing.py +6 -2
- notionary/exceptions/data_source/builder.py +11 -5
- notionary/exceptions/data_source/properties.py +3 -1
- notionary/exceptions/file_upload.py +12 -3
- notionary/exceptions/properties.py +3 -1
- notionary/exceptions/search.py +6 -2
- notionary/file_upload/client.py +5 -1
- notionary/file_upload/config/config.py +10 -3
- notionary/file_upload/query/builder.py +6 -2
- notionary/file_upload/schemas.py +3 -1
- notionary/file_upload/service.py +42 -14
- notionary/file_upload/validation/factory.py +3 -1
- notionary/file_upload/validation/impl/file_name_length.py +3 -1
- notionary/file_upload/validation/models.py +15 -5
- notionary/file_upload/validation/validators/file_extension.py +12 -3
- notionary/http/client.py +27 -8
- notionary/page/content/__init__.py +9 -0
- notionary/page/content/factory.py +21 -7
- notionary/page/content/markdown/builder.py +85 -23
- notionary/page/content/markdown/nodes/audio.py +8 -4
- notionary/page/content/markdown/nodes/base.py +3 -3
- notionary/page/content/markdown/nodes/bookmark.py +5 -3
- notionary/page/content/markdown/nodes/breadcrumb.py +2 -2
- notionary/page/content/markdown/nodes/bulleted_list.py +5 -3
- notionary/page/content/markdown/nodes/callout.py +2 -2
- notionary/page/content/markdown/nodes/code.py +5 -3
- notionary/page/content/markdown/nodes/columns.py +3 -3
- notionary/page/content/markdown/nodes/container.py +9 -5
- notionary/page/content/markdown/nodes/divider.py +2 -2
- notionary/page/content/markdown/nodes/embed.py +8 -4
- notionary/page/content/markdown/nodes/equation.py +4 -2
- notionary/page/content/markdown/nodes/file.py +8 -4
- notionary/page/content/markdown/nodes/heading.py +2 -2
- notionary/page/content/markdown/nodes/image.py +8 -4
- notionary/page/content/markdown/nodes/mixins/caption.py +5 -3
- notionary/page/content/markdown/nodes/numbered_list.py +5 -3
- notionary/page/content/markdown/nodes/paragraph.py +4 -2
- notionary/page/content/markdown/nodes/pdf.py +8 -4
- notionary/page/content/markdown/nodes/quote.py +2 -2
- notionary/page/content/markdown/nodes/space.py +2 -2
- notionary/page/content/markdown/nodes/table.py +8 -5
- notionary/page/content/markdown/nodes/table_of_contents.py +2 -2
- notionary/page/content/markdown/nodes/todo.py +15 -7
- notionary/page/content/markdown/nodes/toggle.py +2 -2
- notionary/page/content/markdown/nodes/video.py +8 -4
- notionary/page/content/markdown/structured_output/__init__.py +73 -0
- notionary/page/content/markdown/structured_output/models.py +391 -0
- notionary/page/content/markdown/structured_output/service.py +211 -0
- notionary/page/content/parser/context.py +1 -1
- notionary/page/content/parser/factory.py +23 -8
- notionary/page/content/parser/parsers/audio.py +7 -2
- notionary/page/content/parser/parsers/base.py +2 -2
- notionary/page/content/parser/parsers/bookmark.py +2 -2
- notionary/page/content/parser/parsers/breadcrumb.py +2 -2
- notionary/page/content/parser/parsers/bulleted_list.py +19 -6
- notionary/page/content/parser/parsers/callout.py +15 -5
- notionary/page/content/parser/parsers/caption.py +9 -3
- notionary/page/content/parser/parsers/code.py +21 -7
- notionary/page/content/parser/parsers/column.py +8 -4
- notionary/page/content/parser/parsers/column_list.py +19 -7
- notionary/page/content/parser/parsers/divider.py +2 -2
- notionary/page/content/parser/parsers/embed.py +2 -2
- notionary/page/content/parser/parsers/equation.py +8 -4
- notionary/page/content/parser/parsers/file.py +7 -2
- notionary/page/content/parser/parsers/file_like_block.py +30 -10
- notionary/page/content/parser/parsers/heading.py +31 -10
- notionary/page/content/parser/parsers/image.py +7 -2
- notionary/page/content/parser/parsers/numbered_list.py +18 -6
- notionary/page/content/parser/parsers/paragraph.py +3 -1
- notionary/page/content/parser/parsers/pdf.py +7 -2
- notionary/page/content/parser/parsers/quote.py +28 -9
- notionary/page/content/parser/parsers/space.py +2 -2
- notionary/page/content/parser/parsers/table.py +31 -10
- notionary/page/content/parser/parsers/table_of_contents.py +7 -3
- notionary/page/content/parser/parsers/todo.py +15 -5
- notionary/page/content/parser/parsers/toggle.py +15 -5
- notionary/page/content/parser/parsers/video.py +7 -2
- notionary/page/content/parser/post_processing/handlers/rich_text_length.py +8 -2
- notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +8 -2
- notionary/page/content/parser/post_processing/service.py +3 -1
- notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +21 -7
- notionary/page/content/parser/pre_processsing/handlers/indentation.py +11 -4
- notionary/page/content/parser/pre_processsing/handlers/video_syntax.py +13 -6
- notionary/page/content/parser/service.py +4 -1
- notionary/page/content/renderer/context.py +15 -5
- notionary/page/content/renderer/factory.py +12 -6
- notionary/page/content/renderer/post_processing/handlers/numbered_list.py +19 -9
- notionary/page/content/renderer/renderers/audio.py +14 -5
- notionary/page/content/renderer/renderers/base.py +3 -3
- notionary/page/content/renderer/renderers/bookmark.py +3 -1
- notionary/page/content/renderer/renderers/bulleted_list.py +11 -5
- notionary/page/content/renderer/renderers/callout.py +19 -7
- notionary/page/content/renderer/renderers/captioned_block.py +11 -5
- notionary/page/content/renderer/renderers/code.py +6 -2
- notionary/page/content/renderer/renderers/column.py +3 -1
- notionary/page/content/renderer/renderers/column_list.py +3 -1
- notionary/page/content/renderer/renderers/embed.py +3 -1
- notionary/page/content/renderer/renderers/equation.py +3 -1
- notionary/page/content/renderer/renderers/file.py +14 -5
- notionary/page/content/renderer/renderers/file_like_block.py +8 -4
- notionary/page/content/renderer/renderers/heading.py +22 -8
- notionary/page/content/renderer/renderers/image.py +13 -4
- notionary/page/content/renderer/renderers/numbered_list.py +8 -3
- notionary/page/content/renderer/renderers/paragraph.py +12 -4
- notionary/page/content/renderer/renderers/pdf.py +14 -5
- notionary/page/content/renderer/renderers/quote.py +14 -6
- notionary/page/content/renderer/renderers/table.py +15 -5
- notionary/page/content/renderer/renderers/todo.py +16 -6
- notionary/page/content/renderer/renderers/toggle.py +8 -4
- notionary/page/content/renderer/renderers/video.py +14 -5
- notionary/page/content/renderer/service.py +9 -3
- notionary/page/content/service.py +21 -7
- notionary/page/content/syntax/definition/__init__.py +11 -0
- notionary/page/content/syntax/definition/models.py +57 -0
- notionary/page/content/syntax/definition/registry.py +371 -0
- notionary/page/content/syntax/prompts/__init__.py +4 -0
- notionary/page/content/syntax/prompts/models.py +11 -0
- notionary/page/content/syntax/prompts/registry.py +703 -0
- notionary/page/page_metadata_update_client.py +12 -4
- notionary/page/properties/client.py +45 -15
- notionary/page/properties/factory.py +6 -2
- notionary/page/properties/service.py +110 -36
- notionary/page/service.py +20 -6
- notionary/shared/entity/client.py +6 -2
- notionary/shared/entity/dto_parsers.py +3 -1
- notionary/shared/entity/entity_metadata_update_client.py +9 -3
- notionary/shared/entity/schemas.py +1 -1
- notionary/shared/entity/service.py +53 -22
- notionary/shared/models/file.py +3 -1
- notionary/shared/models/icon.py +6 -4
- notionary/user/base.py +6 -2
- notionary/user/bot.py +10 -2
- notionary/user/client.py +3 -1
- notionary/user/person.py +3 -1
- notionary/user/schemas.py +3 -1
- notionary/user/service.py +6 -2
- notionary/utils/decorators.py +6 -2
- notionary/utils/fuzzy.py +6 -2
- notionary/utils/mixins/logging.py +3 -1
- notionary/utils/pagination.py +14 -4
- notionary/workspace/__init__.py +5 -1
- notionary/workspace/query/service.py +59 -16
- notionary/workspace/service.py +39 -11
- {notionary-0.4.0.dist-info → notionary-0.4.2.dist-info}/METADATA +1 -1
- notionary-0.4.2.dist-info/RECORD +236 -0
- notionary/page/blocks/client.py +0 -1
- notionary/page/content/syntax/__init__.py +0 -5
- notionary/page/content/syntax/models.py +0 -66
- notionary/page/content/syntax/registry.py +0 -371
- notionary-0.4.0.dist-info/RECORD +0 -230
- /notionary/page/content/syntax/{grammar.py → definition/grammar.py} +0 -0
- {notionary-0.4.0.dist-info → notionary-0.4.2.dist-info}/WHEEL +0 -0
- {notionary-0.4.0.dist-info → notionary-0.4.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,7 +2,9 @@ from typing import override
|
|
|
2
2
|
|
|
3
3
|
from notionary.http.client import NotionHttpClient
|
|
4
4
|
from notionary.page.schemas import NotionPageDto
|
|
5
|
-
from notionary.shared.entity.entity_metadata_update_client import
|
|
5
|
+
from notionary.shared.entity.entity_metadata_update_client import (
|
|
6
|
+
EntityMetadataUpdateClient,
|
|
7
|
+
)
|
|
6
8
|
from notionary.shared.entity.schemas import NotionEntityUpdateDto
|
|
7
9
|
|
|
8
10
|
|
|
@@ -12,8 +14,14 @@ class PageMetadataUpdateClient(NotionHttpClient, EntityMetadataUpdateClient):
|
|
|
12
14
|
self._page_id = page_id
|
|
13
15
|
|
|
14
16
|
@override
|
|
15
|
-
async def patch_metadata(
|
|
16
|
-
|
|
17
|
+
async def patch_metadata(
|
|
18
|
+
self, updated_data: NotionEntityUpdateDto
|
|
19
|
+
) -> NotionPageDto:
|
|
20
|
+
updated_data_dict = updated_data.model_dump(
|
|
21
|
+
exclude_unset=True, exclude_none=True
|
|
22
|
+
)
|
|
17
23
|
|
|
18
|
-
response_dict = await self.patch(
|
|
24
|
+
response_dict = await self.patch(
|
|
25
|
+
f"pages/{self._page_id}", data=updated_data_dict
|
|
26
|
+
)
|
|
19
27
|
return NotionPageDto.model_validate(response_dict)
|
|
@@ -44,7 +44,9 @@ class PagePropertyHttpClient(NotionHttpClient):
|
|
|
44
44
|
property_type: type[PagePropertyT],
|
|
45
45
|
current_property: PagePropertyT | None = None,
|
|
46
46
|
) -> NotionPageDto:
|
|
47
|
-
updated_property = self._create_updated_property(
|
|
47
|
+
updated_property = self._create_updated_property(
|
|
48
|
+
property_type, current_property, value
|
|
49
|
+
)
|
|
48
50
|
|
|
49
51
|
properties = {property_name: updated_property}
|
|
50
52
|
update_dto = PgePropertiesUpdateDto(properties=properties)
|
|
@@ -54,40 +56,64 @@ class PagePropertyHttpClient(NotionHttpClient):
|
|
|
54
56
|
async def patch_title(self, property_name: str, title: str) -> NotionPageDto:
|
|
55
57
|
return await self._patch_property(property_name, title, PageTitleProperty)
|
|
56
58
|
|
|
57
|
-
async def patch_rich_text_property(
|
|
59
|
+
async def patch_rich_text_property(
|
|
60
|
+
self, property_name: str, text: str
|
|
61
|
+
) -> NotionPageDto:
|
|
58
62
|
return await self._patch_property(property_name, text, PageRichTextProperty)
|
|
59
63
|
|
|
60
64
|
async def patch_url_property(self, property_name: str, url: str) -> NotionPageDto:
|
|
61
65
|
return await self._patch_property(property_name, url, PageURLProperty)
|
|
62
66
|
|
|
63
|
-
async def patch_email_property(
|
|
67
|
+
async def patch_email_property(
|
|
68
|
+
self, property_name: str, email: str
|
|
69
|
+
) -> NotionPageDto:
|
|
64
70
|
return await self._patch_property(property_name, email, PageEmailProperty)
|
|
65
71
|
|
|
66
|
-
async def patch_phone_property(
|
|
72
|
+
async def patch_phone_property(
|
|
73
|
+
self, property_name: str, phone: str
|
|
74
|
+
) -> NotionPageDto:
|
|
67
75
|
return await self._patch_property(property_name, phone, PagePhoneNumberProperty)
|
|
68
76
|
|
|
69
|
-
async def patch_number_property(
|
|
77
|
+
async def patch_number_property(
|
|
78
|
+
self, property_name: str, number: int | float
|
|
79
|
+
) -> NotionPageDto:
|
|
70
80
|
return await self._patch_property(property_name, number, PageNumberProperty)
|
|
71
81
|
|
|
72
|
-
async def patch_checkbox_property(
|
|
82
|
+
async def patch_checkbox_property(
|
|
83
|
+
self, property_name: str, checked: bool
|
|
84
|
+
) -> NotionPageDto:
|
|
73
85
|
return await self._patch_property(property_name, checked, PageCheckboxProperty)
|
|
74
86
|
|
|
75
|
-
async def patch_select_property(
|
|
87
|
+
async def patch_select_property(
|
|
88
|
+
self, property_name: str, value: str
|
|
89
|
+
) -> NotionPageDto:
|
|
76
90
|
return await self._patch_property(property_name, value, PageSelectProperty)
|
|
77
91
|
|
|
78
|
-
async def patch_multi_select_property(
|
|
79
|
-
|
|
92
|
+
async def patch_multi_select_property(
|
|
93
|
+
self, property_name: str, values: list[str]
|
|
94
|
+
) -> NotionPageDto:
|
|
95
|
+
return await self._patch_property(
|
|
96
|
+
property_name, values, PageMultiSelectProperty
|
|
97
|
+
)
|
|
80
98
|
|
|
81
|
-
async def patch_date_property(
|
|
99
|
+
async def patch_date_property(
|
|
100
|
+
self, property_name: str, date_value: str | dict
|
|
101
|
+
) -> NotionPageDto:
|
|
82
102
|
return await self._patch_property(property_name, date_value, PageDateProperty)
|
|
83
103
|
|
|
84
|
-
async def patch_status_property(
|
|
104
|
+
async def patch_status_property(
|
|
105
|
+
self, property_name: str, status: str
|
|
106
|
+
) -> NotionPageDto:
|
|
85
107
|
return await self._patch_property(property_name, status, PageStatusProperty)
|
|
86
108
|
|
|
87
|
-
async def patch_relation_property(
|
|
109
|
+
async def patch_relation_property(
|
|
110
|
+
self, property_name: str, relation_ids: str | list[str]
|
|
111
|
+
) -> NotionPageDto:
|
|
88
112
|
if isinstance(relation_ids, str):
|
|
89
113
|
relation_ids = [relation_ids]
|
|
90
|
-
return await self._patch_property(
|
|
114
|
+
return await self._patch_property(
|
|
115
|
+
property_name, relation_ids, PageRelationProperty
|
|
116
|
+
)
|
|
91
117
|
|
|
92
118
|
# TODO: Fix this shit here
|
|
93
119
|
def _create_updated_property(
|
|
@@ -126,8 +152,12 @@ class PagePropertyHttpClient(NotionHttpClient):
|
|
|
126
152
|
select_option = SelectOption(name=str(value))
|
|
127
153
|
return PageSelectProperty(id=property_id, select=select_option)
|
|
128
154
|
elif property_type == PageMultiSelectProperty:
|
|
129
|
-
multi_select_options = [
|
|
130
|
-
|
|
155
|
+
multi_select_options = [
|
|
156
|
+
SelectOption(id="", name=str(item)) for item in value
|
|
157
|
+
]
|
|
158
|
+
return PageMultiSelectProperty(
|
|
159
|
+
id=property_id, multi_select=multi_select_options
|
|
160
|
+
)
|
|
131
161
|
elif property_type == PageDateProperty:
|
|
132
162
|
if isinstance(value, dict) and "start" in value:
|
|
133
163
|
date_value = DateValue(**value)
|
|
@@ -7,12 +7,16 @@ from notionary.shared.models.parent import DataSourceParent, ParentType
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class PagePropertyHandlerFactory:
|
|
10
|
-
def create_from_page_response(
|
|
10
|
+
def create_from_page_response(
|
|
11
|
+
self, page_response: NotionPageDto
|
|
12
|
+
) -> PagePropertyHandler:
|
|
11
13
|
return PagePropertyHandler(
|
|
12
14
|
properties=page_response.properties,
|
|
13
15
|
parent_type=page_response.parent.type,
|
|
14
16
|
page_url=page_response.url,
|
|
15
|
-
page_property_http_client=self._create_http_client(
|
|
17
|
+
page_property_http_client=self._create_http_client(
|
|
18
|
+
page_id=page_response.id
|
|
19
|
+
),
|
|
16
20
|
parent_data_source=self._extract_parent_data_source_id(page_response),
|
|
17
21
|
)
|
|
18
22
|
|
|
@@ -3,7 +3,9 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from typing import TYPE_CHECKING, Never
|
|
5
5
|
|
|
6
|
-
from notionary.blocks.rich_text.rich_text_markdown_converter import
|
|
6
|
+
from notionary.blocks.rich_text.rich_text_markdown_converter import (
|
|
7
|
+
convert_rich_text_to_markdown,
|
|
8
|
+
)
|
|
7
9
|
from notionary.exceptions.properties import (
|
|
8
10
|
AccessPagePropertyWithoutDataSourceError,
|
|
9
11
|
PagePropertyNotFoundError,
|
|
@@ -68,23 +70,33 @@ class PagePropertyHandler:
|
|
|
68
70
|
return await convert_rich_text_to_markdown(title_property.title)
|
|
69
71
|
|
|
70
72
|
def get_values_of_people_property(self, property_name: str) -> list[str]:
|
|
71
|
-
people_prop = self._get_typed_property_or_raise(
|
|
73
|
+
people_prop = self._get_typed_property_or_raise(
|
|
74
|
+
property_name, PagePeopleProperty
|
|
75
|
+
)
|
|
72
76
|
return [person.name for person in people_prop.people if person.name]
|
|
73
77
|
|
|
74
78
|
def get_value_of_created_time_property(self, name: str) -> str | None:
|
|
75
|
-
created_time_property = self._get_typed_property_or_raise(
|
|
79
|
+
created_time_property = self._get_typed_property_or_raise(
|
|
80
|
+
name, PageCreatedTimeProperty
|
|
81
|
+
)
|
|
76
82
|
return created_time_property.created_time
|
|
77
83
|
|
|
78
84
|
async def get_values_of_relation_property(self, name: str) -> list[str]:
|
|
79
85
|
from notionary import NotionPage
|
|
80
86
|
|
|
81
|
-
relation_property = self._get_typed_property_or_raise(
|
|
87
|
+
relation_property = self._get_typed_property_or_raise(
|
|
88
|
+
name, PageRelationProperty
|
|
89
|
+
)
|
|
82
90
|
relation_page_ids = [rel.id for rel in relation_property.relation]
|
|
83
|
-
notion_pages = [
|
|
91
|
+
notion_pages = [
|
|
92
|
+
await NotionPage.from_id(page_id) for page_id in relation_page_ids
|
|
93
|
+
]
|
|
84
94
|
return [page.title for page in notion_pages if page]
|
|
85
95
|
|
|
86
96
|
def get_values_of_multiselect_property(self, name: str) -> list[str]:
|
|
87
|
-
multiselect_property = self._get_typed_property_or_raise(
|
|
97
|
+
multiselect_property = self._get_typed_property_or_raise(
|
|
98
|
+
name, PageMultiSelectProperty
|
|
99
|
+
)
|
|
88
100
|
return [option.name for option in multiselect_property.multi_select]
|
|
89
101
|
|
|
90
102
|
def get_value_of_url_property(self, name: str) -> str | None:
|
|
@@ -96,7 +108,9 @@ class PagePropertyHandler:
|
|
|
96
108
|
return number_property.number
|
|
97
109
|
|
|
98
110
|
def get_value_of_checkbox_property(self, name: str) -> bool:
|
|
99
|
-
checkbox_property = self._get_typed_property_or_raise(
|
|
111
|
+
checkbox_property = self._get_typed_property_or_raise(
|
|
112
|
+
name, PageCheckboxProperty
|
|
113
|
+
)
|
|
100
114
|
return checkbox_property.checkbox
|
|
101
115
|
|
|
102
116
|
def get_value_of_date_property(self, name: str) -> str | None:
|
|
@@ -104,7 +118,9 @@ class PagePropertyHandler:
|
|
|
104
118
|
return date_property.date.start if date_property.date else None
|
|
105
119
|
|
|
106
120
|
async def get_value_of_rich_text_property(self, name: str) -> str:
|
|
107
|
-
rich_text_property = self._get_typed_property_or_raise(
|
|
121
|
+
rich_text_property = self._get_typed_property_or_raise(
|
|
122
|
+
name, PageRichTextProperty
|
|
123
|
+
)
|
|
108
124
|
return await convert_rich_text_to_markdown(rich_text_property.rich_text)
|
|
109
125
|
|
|
110
126
|
def get_value_of_email_property(self, name: str) -> str | None:
|
|
@@ -112,26 +128,36 @@ class PagePropertyHandler:
|
|
|
112
128
|
return email_property.email
|
|
113
129
|
|
|
114
130
|
def get_value_of_phone_number_property(self, name: str) -> str | None:
|
|
115
|
-
phone_property = self._get_typed_property_or_raise(
|
|
131
|
+
phone_property = self._get_typed_property_or_raise(
|
|
132
|
+
name, PagePhoneNumberProperty
|
|
133
|
+
)
|
|
116
134
|
return phone_property.phone_number
|
|
117
135
|
|
|
118
136
|
# =========================================================================
|
|
119
137
|
# Options Getters
|
|
120
138
|
# =========================================================================
|
|
121
139
|
|
|
122
|
-
async def get_select_options_by_property_name(
|
|
140
|
+
async def get_select_options_by_property_name(
|
|
141
|
+
self, property_name: str
|
|
142
|
+
) -> list[str]:
|
|
123
143
|
data_source = await self._get_parent_data_source_or_raise()
|
|
124
144
|
return data_source.get_select_options_by_property_name(property_name)
|
|
125
145
|
|
|
126
|
-
async def get_multi_select_options_by_property_name(
|
|
146
|
+
async def get_multi_select_options_by_property_name(
|
|
147
|
+
self, property_name: str
|
|
148
|
+
) -> list[str]:
|
|
127
149
|
data_source = await self._get_parent_data_source_or_raise()
|
|
128
150
|
return data_source.get_multi_select_options_by_property_name(property_name)
|
|
129
151
|
|
|
130
|
-
async def get_status_options_by_property_name(
|
|
152
|
+
async def get_status_options_by_property_name(
|
|
153
|
+
self, property_name: str
|
|
154
|
+
) -> list[str]:
|
|
131
155
|
data_source = await self._get_parent_data_source_or_raise()
|
|
132
156
|
return data_source.get_status_options_by_property_name(property_name)
|
|
133
157
|
|
|
134
|
-
async def get_relation_options_by_property_name(
|
|
158
|
+
async def get_relation_options_by_property_name(
|
|
159
|
+
self, property_name: str
|
|
160
|
+
) -> list[str]:
|
|
135
161
|
data_source = await self._get_parent_data_source_or_raise()
|
|
136
162
|
return await data_source.get_relation_options_by_property_name(property_name)
|
|
137
163
|
|
|
@@ -151,7 +177,9 @@ class PagePropertyHandler:
|
|
|
151
177
|
title_property_name = self._extract_title_property_name()
|
|
152
178
|
|
|
153
179
|
self._get_typed_property_or_raise(title_property_name, PageTitleProperty)
|
|
154
|
-
updated_page = await self._property_http_client.patch_title(
|
|
180
|
+
updated_page = await self._property_http_client.patch_title(
|
|
181
|
+
title_property_name, title
|
|
182
|
+
)
|
|
155
183
|
self._properties = updated_page.properties
|
|
156
184
|
|
|
157
185
|
def _extract_title_property_name(self) -> str | None:
|
|
@@ -159,64 +187,104 @@ class PagePropertyHandler:
|
|
|
159
187
|
return None
|
|
160
188
|
|
|
161
189
|
return next(
|
|
162
|
-
(
|
|
190
|
+
(
|
|
191
|
+
key
|
|
192
|
+
for key, prop in self._properties.items()
|
|
193
|
+
if isinstance(prop, PageTitleProperty)
|
|
194
|
+
),
|
|
163
195
|
None,
|
|
164
196
|
)
|
|
165
197
|
|
|
166
198
|
async def set_rich_text_property(self, property_name: str, text: str) -> None:
|
|
167
199
|
self._get_typed_property_or_raise(property_name, PageRichTextProperty)
|
|
168
|
-
updated_page = await self._property_http_client.patch_rich_text_property(
|
|
200
|
+
updated_page = await self._property_http_client.patch_rich_text_property(
|
|
201
|
+
property_name, text
|
|
202
|
+
)
|
|
169
203
|
self._properties = updated_page.properties
|
|
170
204
|
|
|
171
205
|
async def set_url_property(self, property_name: str, url: str) -> None:
|
|
172
206
|
self._get_typed_property_or_raise(property_name, PageURLProperty)
|
|
173
|
-
updated_page = await self._property_http_client.patch_url_property(
|
|
207
|
+
updated_page = await self._property_http_client.patch_url_property(
|
|
208
|
+
property_name, url
|
|
209
|
+
)
|
|
174
210
|
self._properties = updated_page.properties
|
|
175
211
|
|
|
176
212
|
async def set_email_property(self, property_name: str, email: str) -> None:
|
|
177
213
|
self._get_typed_property_or_raise(property_name, PageEmailProperty)
|
|
178
|
-
updated_page = await self._property_http_client.patch_email_property(
|
|
214
|
+
updated_page = await self._property_http_client.patch_email_property(
|
|
215
|
+
property_name, email
|
|
216
|
+
)
|
|
179
217
|
self._properties = updated_page.properties
|
|
180
218
|
|
|
181
|
-
async def set_phone_number_property(
|
|
219
|
+
async def set_phone_number_property(
|
|
220
|
+
self, property_name: str, phone_number: str
|
|
221
|
+
) -> None:
|
|
182
222
|
self._get_typed_property_or_raise(property_name, PagePhoneNumberProperty)
|
|
183
|
-
updated_page = await self._property_http_client.patch_phone_property(
|
|
223
|
+
updated_page = await self._property_http_client.patch_phone_property(
|
|
224
|
+
property_name, phone_number
|
|
225
|
+
)
|
|
184
226
|
self._properties = updated_page.properties
|
|
185
227
|
|
|
186
|
-
async def set_number_property(
|
|
228
|
+
async def set_number_property(
|
|
229
|
+
self, property_name: str, number: int | float
|
|
230
|
+
) -> None:
|
|
187
231
|
self._get_typed_property_or_raise(property_name, PageNumberProperty)
|
|
188
|
-
updated_page = await self._property_http_client.patch_number_property(
|
|
232
|
+
updated_page = await self._property_http_client.patch_number_property(
|
|
233
|
+
property_name, number
|
|
234
|
+
)
|
|
189
235
|
self._properties = updated_page.properties
|
|
190
236
|
|
|
191
237
|
async def set_checkbox_property(self, property_name: str, checked: bool) -> None:
|
|
192
238
|
self._get_typed_property_or_raise(property_name, PageCheckboxProperty)
|
|
193
|
-
updated_page = await self._property_http_client.patch_checkbox_property(
|
|
239
|
+
updated_page = await self._property_http_client.patch_checkbox_property(
|
|
240
|
+
property_name, checked
|
|
241
|
+
)
|
|
194
242
|
self._properties = updated_page.properties
|
|
195
243
|
|
|
196
|
-
async def set_date_property(
|
|
244
|
+
async def set_date_property(
|
|
245
|
+
self, property_name: str, date_value: str | dict
|
|
246
|
+
) -> None:
|
|
197
247
|
self._get_typed_property_or_raise(property_name, PageDateProperty)
|
|
198
|
-
updated_page = await self._property_http_client.patch_date_property(
|
|
248
|
+
updated_page = await self._property_http_client.patch_date_property(
|
|
249
|
+
property_name, date_value
|
|
250
|
+
)
|
|
199
251
|
self._properties = updated_page.properties
|
|
200
252
|
|
|
201
|
-
async def set_select_property_by_option_name(
|
|
253
|
+
async def set_select_property_by_option_name(
|
|
254
|
+
self, property_name: str, option_name: str
|
|
255
|
+
) -> None:
|
|
202
256
|
self._get_typed_property_or_raise(property_name, PageSelectProperty)
|
|
203
|
-
updated_page = await self._property_http_client.patch_select_property(
|
|
257
|
+
updated_page = await self._property_http_client.patch_select_property(
|
|
258
|
+
property_name, option_name
|
|
259
|
+
)
|
|
204
260
|
self._properties = updated_page.properties
|
|
205
261
|
|
|
206
|
-
async def set_multi_select_property_by_option_names(
|
|
262
|
+
async def set_multi_select_property_by_option_names(
|
|
263
|
+
self, property_name: str, option_names: list[str]
|
|
264
|
+
) -> None:
|
|
207
265
|
self._get_typed_property_or_raise(property_name, PageMultiSelectProperty)
|
|
208
|
-
updated_page = await self._property_http_client.patch_multi_select_property(
|
|
266
|
+
updated_page = await self._property_http_client.patch_multi_select_property(
|
|
267
|
+
property_name, option_names
|
|
268
|
+
)
|
|
209
269
|
self._properties = updated_page.properties
|
|
210
270
|
|
|
211
|
-
async def set_status_property_by_option_name(
|
|
271
|
+
async def set_status_property_by_option_name(
|
|
272
|
+
self, property_name: str, status: str
|
|
273
|
+
) -> None:
|
|
212
274
|
self._get_typed_property_or_raise(property_name, PageStatusProperty)
|
|
213
|
-
updated_page = await self._property_http_client.patch_status_property(
|
|
275
|
+
updated_page = await self._property_http_client.patch_status_property(
|
|
276
|
+
property_name, status
|
|
277
|
+
)
|
|
214
278
|
self._properties = updated_page.properties
|
|
215
279
|
|
|
216
|
-
async def set_relation_property_by_page_titles(
|
|
280
|
+
async def set_relation_property_by_page_titles(
|
|
281
|
+
self, property_name: str, page_titles: list[str]
|
|
282
|
+
) -> None:
|
|
217
283
|
self._get_typed_property_or_raise(property_name, PageRelationProperty)
|
|
218
284
|
relation_ids = await self._convert_page_titles_to_ids(page_titles)
|
|
219
|
-
updated_page = await self._property_http_client.patch_relation_property(
|
|
285
|
+
updated_page = await self._property_http_client.patch_relation_property(
|
|
286
|
+
property_name, relation_ids
|
|
287
|
+
)
|
|
220
288
|
self._properties = updated_page.properties
|
|
221
289
|
|
|
222
290
|
async def _ensure_data_source_loaded(self) -> None:
|
|
@@ -226,7 +294,9 @@ class PagePropertyHandler:
|
|
|
226
294
|
return
|
|
227
295
|
|
|
228
296
|
self._parent_data_source = (
|
|
229
|
-
await NotionDataSource.from_id(self._parent_data_source_id)
|
|
297
|
+
await NotionDataSource.from_id(self._parent_data_source_id)
|
|
298
|
+
if self._parent_data_source_id
|
|
299
|
+
else None
|
|
230
300
|
)
|
|
231
301
|
self._data_source_loaded = True
|
|
232
302
|
|
|
@@ -237,7 +307,9 @@ class PagePropertyHandler:
|
|
|
237
307
|
raise AccessPagePropertyWithoutDataSourceError(self._parent_type)
|
|
238
308
|
return self._parent_data_source
|
|
239
309
|
|
|
240
|
-
def _get_typed_property_or_raise(
|
|
310
|
+
def _get_typed_property_or_raise(
|
|
311
|
+
self, name: str, property_type: type[PagePropertyT]
|
|
312
|
+
) -> PagePropertyT:
|
|
241
313
|
prop = self._properties.get(name)
|
|
242
314
|
|
|
243
315
|
if prop is None:
|
|
@@ -267,6 +339,8 @@ class PagePropertyHandler:
|
|
|
267
339
|
if not page_titles:
|
|
268
340
|
return []
|
|
269
341
|
|
|
270
|
-
pages = await asyncio.gather(
|
|
342
|
+
pages = await asyncio.gather(
|
|
343
|
+
*[NotionPage.from_title(title=title) for title in page_titles]
|
|
344
|
+
)
|
|
271
345
|
|
|
272
346
|
return [page.id for page in pages if page]
|
notionary/page/service.py
CHANGED
|
@@ -2,7 +2,9 @@ from collections.abc import Callable
|
|
|
2
2
|
from typing import Self
|
|
3
3
|
|
|
4
4
|
from notionary.blocks.client import NotionBlockHttpClient
|
|
5
|
-
from notionary.blocks.rich_text.rich_text_markdown_converter import
|
|
5
|
+
from notionary.blocks.rich_text.rich_text_markdown_converter import (
|
|
6
|
+
convert_rich_text_to_markdown,
|
|
7
|
+
)
|
|
6
8
|
from notionary.comments.models import Comment
|
|
7
9
|
from notionary.comments.service import CommentService
|
|
8
10
|
from notionary.page.content.factory import PageContentServiceFactory
|
|
@@ -71,7 +73,9 @@ class NotionPage(Entity):
|
|
|
71
73
|
page_property_handler_factory: PagePropertyHandlerFactory,
|
|
72
74
|
) -> Self:
|
|
73
75
|
title_task = cls._extract_title_from_dto(dto)
|
|
74
|
-
page_property_handler = page_property_handler_factory.create_from_page_response(
|
|
76
|
+
page_property_handler = page_property_handler_factory.create_from_page_response(
|
|
77
|
+
dto
|
|
78
|
+
)
|
|
75
79
|
|
|
76
80
|
title = await title_task
|
|
77
81
|
|
|
@@ -92,7 +96,9 @@ class NotionPage(Entity):
|
|
|
92
96
|
comment_service = CommentService()
|
|
93
97
|
|
|
94
98
|
page_content_service_factory = PageContentServiceFactory()
|
|
95
|
-
page_content_service = page_content_service_factory.create(
|
|
99
|
+
page_content_service = page_content_service_factory.create(
|
|
100
|
+
page_id=dto.id, block_client=block_client
|
|
101
|
+
)
|
|
96
102
|
|
|
97
103
|
metadata_update_client = PageMetadataUpdateClient(page_id=dto.id)
|
|
98
104
|
|
|
@@ -109,7 +115,11 @@ class NotionPage(Entity):
|
|
|
109
115
|
@staticmethod
|
|
110
116
|
async def _extract_title_from_dto(response: NotionPageDto) -> str:
|
|
111
117
|
title_property = next(
|
|
112
|
-
(
|
|
118
|
+
(
|
|
119
|
+
prop
|
|
120
|
+
for prop in response.properties.values()
|
|
121
|
+
if isinstance(prop, PageTitleProperty)
|
|
122
|
+
),
|
|
113
123
|
None,
|
|
114
124
|
)
|
|
115
125
|
rich_text_title = title_property.title if title_property else []
|
|
@@ -135,10 +145,14 @@ class NotionPage(Entity):
|
|
|
135
145
|
return await self._comment_service.list_all_comments_for_page(page_id=self._id)
|
|
136
146
|
|
|
137
147
|
async def post_top_level_comment(self, comment: str) -> None:
|
|
138
|
-
await self._comment_service.create_comment_on_page(
|
|
148
|
+
await self._comment_service.create_comment_on_page(
|
|
149
|
+
page_id=self._id, text=comment
|
|
150
|
+
)
|
|
139
151
|
|
|
140
152
|
async def post_reply_to_discussion(self, discussion_id: str, comment: str) -> None:
|
|
141
|
-
await self._comment_service.reply_to_discussion_by_id(
|
|
153
|
+
await self._comment_service.reply_to_discussion_by_id(
|
|
154
|
+
discussion_id=discussion_id, text=comment
|
|
155
|
+
)
|
|
142
156
|
|
|
143
157
|
async def set_title(self, title: str) -> None:
|
|
144
158
|
await self.properties.set_title_property(title)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from typing import TypeVar, override
|
|
2
2
|
|
|
3
3
|
from notionary.http.client import NotionHttpClient
|
|
4
|
-
from notionary.shared.entity.entity_metadata_update_client import
|
|
4
|
+
from notionary.shared.entity.entity_metadata_update_client import (
|
|
5
|
+
EntityMetadataUpdateClient,
|
|
6
|
+
)
|
|
5
7
|
from notionary.shared.entity.schemas import EntityResponseDto, NotionEntityUpdateDto
|
|
6
8
|
|
|
7
9
|
ResponseType = TypeVar("ResponseType", bound=EntityResponseDto)
|
|
@@ -22,7 +24,9 @@ class GenericEntityMetadataUpdateClient(NotionHttpClient, EntityMetadataUpdateCl
|
|
|
22
24
|
|
|
23
25
|
@override
|
|
24
26
|
async def patch_metadata(self, updated_data: NotionEntityUpdateDto) -> ResponseType:
|
|
25
|
-
updated_data_dict = updated_data.model_dump(
|
|
27
|
+
updated_data_dict = updated_data.model_dump(
|
|
28
|
+
exclude_unset=True, exclude_none=True
|
|
29
|
+
)
|
|
26
30
|
url = f"{self._path_segment}/{self._entity_id}"
|
|
27
31
|
|
|
28
32
|
response_dict = await self.patch(url, data=updated_data_dict)
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
from notionary.blocks.rich_text.rich_text_markdown_converter import
|
|
1
|
+
from notionary.blocks.rich_text.rich_text_markdown_converter import (
|
|
2
|
+
RichTextToMarkdownConverter,
|
|
3
|
+
)
|
|
2
4
|
from notionary.shared.entity.schemas import Describable, Titled
|
|
3
5
|
|
|
4
6
|
|
|
@@ -7,7 +7,9 @@ from notionary.shared.models.icon import EmojiIcon, Icon
|
|
|
7
7
|
|
|
8
8
|
class EntityMetadataUpdateClient(ABC):
|
|
9
9
|
@abstractmethod
|
|
10
|
-
async def patch_metadata(
|
|
10
|
+
async def patch_metadata(
|
|
11
|
+
self, updated_data: NotionEntityUpdateDto
|
|
12
|
+
) -> EntityResponseDto: ...
|
|
11
13
|
|
|
12
14
|
async def patch_emoji_icon(self, emoji: str) -> EntityResponseDto:
|
|
13
15
|
icon = EmojiIcon(emoji=emoji)
|
|
@@ -18,7 +20,9 @@ class EntityMetadataUpdateClient(ABC):
|
|
|
18
20
|
icon = ExternalFile.from_url(icon_url)
|
|
19
21
|
return await self._patch_icon(icon)
|
|
20
22
|
|
|
21
|
-
async def patch_icon_from_file_upload(
|
|
23
|
+
async def patch_icon_from_file_upload(
|
|
24
|
+
self, file_upload_id: str
|
|
25
|
+
) -> EntityResponseDto:
|
|
22
26
|
icon = FileUploadFile.from_id(id=file_upload_id)
|
|
23
27
|
return await self._patch_icon(icon)
|
|
24
28
|
|
|
@@ -34,7 +38,9 @@ class EntityMetadataUpdateClient(ABC):
|
|
|
34
38
|
cover = ExternalFile.from_url(cover_url)
|
|
35
39
|
return await self._patch_cover(cover)
|
|
36
40
|
|
|
37
|
-
async def patch_cover_from_file_upload(
|
|
41
|
+
async def patch_cover_from_file_upload(
|
|
42
|
+
self, file_upload_id: str
|
|
43
|
+
) -> EntityResponseDto:
|
|
38
44
|
cover = FileUploadFile.from_id(id=file_upload_id)
|
|
39
45
|
return await self._patch_cover(cover)
|
|
40
46
|
|