notionary 0.4.0__py3-none-any.whl → 0.4.1__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.
Files changed (176) hide show
  1. notionary/__init__.py +44 -1
  2. notionary/blocks/client.py +37 -11
  3. notionary/blocks/rich_text/markdown_rich_text_converter.py +49 -15
  4. notionary/blocks/rich_text/models.py +13 -4
  5. notionary/blocks/rich_text/name_id_resolver/data_source.py +9 -3
  6. notionary/blocks/rich_text/name_id_resolver/person.py +6 -2
  7. notionary/blocks/rich_text/rich_text_markdown_converter.py +10 -3
  8. notionary/blocks/schemas.py +2 -1
  9. notionary/comments/client.py +19 -6
  10. notionary/comments/factory.py +10 -3
  11. notionary/comments/schemas.py +9 -3
  12. notionary/comments/service.py +12 -4
  13. notionary/data_source/http/data_source_instance_client.py +59 -17
  14. notionary/data_source/properties/schemas.py +30 -10
  15. notionary/data_source/query/builder.py +67 -18
  16. notionary/data_source/query/resolver.py +16 -5
  17. notionary/data_source/query/schema.py +24 -6
  18. notionary/data_source/query/validator.py +18 -6
  19. notionary/data_source/schema/registry.py +31 -12
  20. notionary/data_source/schema/service.py +66 -20
  21. notionary/data_source/service.py +74 -23
  22. notionary/database/client.py +27 -9
  23. notionary/database/database_metadata_update_client.py +12 -4
  24. notionary/database/service.py +11 -4
  25. notionary/exceptions/__init__.py +15 -3
  26. notionary/exceptions/block_parsing.py +6 -2
  27. notionary/exceptions/data_source/builder.py +11 -5
  28. notionary/exceptions/data_source/properties.py +3 -1
  29. notionary/exceptions/file_upload.py +12 -3
  30. notionary/exceptions/properties.py +3 -1
  31. notionary/exceptions/search.py +6 -2
  32. notionary/file_upload/client.py +5 -1
  33. notionary/file_upload/config/config.py +10 -3
  34. notionary/file_upload/query/builder.py +6 -2
  35. notionary/file_upload/schemas.py +3 -1
  36. notionary/file_upload/service.py +42 -14
  37. notionary/file_upload/validation/factory.py +3 -1
  38. notionary/file_upload/validation/impl/file_name_length.py +3 -1
  39. notionary/file_upload/validation/models.py +15 -5
  40. notionary/file_upload/validation/validators/file_extension.py +12 -3
  41. notionary/http/client.py +27 -8
  42. notionary/page/content/__init__.py +9 -0
  43. notionary/page/content/factory.py +21 -7
  44. notionary/page/content/markdown/builder.py +85 -23
  45. notionary/page/content/markdown/nodes/audio.py +8 -4
  46. notionary/page/content/markdown/nodes/base.py +3 -3
  47. notionary/page/content/markdown/nodes/bookmark.py +5 -3
  48. notionary/page/content/markdown/nodes/breadcrumb.py +2 -2
  49. notionary/page/content/markdown/nodes/bulleted_list.py +5 -3
  50. notionary/page/content/markdown/nodes/callout.py +2 -2
  51. notionary/page/content/markdown/nodes/code.py +5 -3
  52. notionary/page/content/markdown/nodes/columns.py +3 -3
  53. notionary/page/content/markdown/nodes/container.py +9 -5
  54. notionary/page/content/markdown/nodes/divider.py +2 -2
  55. notionary/page/content/markdown/nodes/embed.py +8 -4
  56. notionary/page/content/markdown/nodes/equation.py +4 -2
  57. notionary/page/content/markdown/nodes/file.py +8 -4
  58. notionary/page/content/markdown/nodes/heading.py +2 -2
  59. notionary/page/content/markdown/nodes/image.py +8 -4
  60. notionary/page/content/markdown/nodes/mixins/caption.py +5 -3
  61. notionary/page/content/markdown/nodes/numbered_list.py +5 -3
  62. notionary/page/content/markdown/nodes/paragraph.py +4 -2
  63. notionary/page/content/markdown/nodes/pdf.py +8 -4
  64. notionary/page/content/markdown/nodes/quote.py +2 -2
  65. notionary/page/content/markdown/nodes/space.py +2 -2
  66. notionary/page/content/markdown/nodes/table.py +8 -5
  67. notionary/page/content/markdown/nodes/table_of_contents.py +2 -2
  68. notionary/page/content/markdown/nodes/todo.py +15 -7
  69. notionary/page/content/markdown/nodes/toggle.py +2 -2
  70. notionary/page/content/markdown/nodes/video.py +8 -4
  71. notionary/page/content/markdown/structured_output/__init__.py +73 -0
  72. notionary/page/content/markdown/structured_output/models.py +391 -0
  73. notionary/page/content/markdown/structured_output/service.py +211 -0
  74. notionary/page/content/parser/context.py +1 -1
  75. notionary/page/content/parser/factory.py +23 -8
  76. notionary/page/content/parser/parsers/audio.py +7 -2
  77. notionary/page/content/parser/parsers/base.py +2 -2
  78. notionary/page/content/parser/parsers/bookmark.py +2 -2
  79. notionary/page/content/parser/parsers/breadcrumb.py +2 -2
  80. notionary/page/content/parser/parsers/bulleted_list.py +19 -6
  81. notionary/page/content/parser/parsers/callout.py +15 -5
  82. notionary/page/content/parser/parsers/caption.py +9 -3
  83. notionary/page/content/parser/parsers/code.py +21 -7
  84. notionary/page/content/parser/parsers/column.py +8 -4
  85. notionary/page/content/parser/parsers/column_list.py +19 -7
  86. notionary/page/content/parser/parsers/divider.py +2 -2
  87. notionary/page/content/parser/parsers/embed.py +2 -2
  88. notionary/page/content/parser/parsers/equation.py +8 -4
  89. notionary/page/content/parser/parsers/file.py +7 -2
  90. notionary/page/content/parser/parsers/file_like_block.py +30 -10
  91. notionary/page/content/parser/parsers/heading.py +31 -10
  92. notionary/page/content/parser/parsers/image.py +7 -2
  93. notionary/page/content/parser/parsers/numbered_list.py +18 -6
  94. notionary/page/content/parser/parsers/paragraph.py +3 -1
  95. notionary/page/content/parser/parsers/pdf.py +7 -2
  96. notionary/page/content/parser/parsers/quote.py +28 -9
  97. notionary/page/content/parser/parsers/space.py +2 -2
  98. notionary/page/content/parser/parsers/table.py +31 -10
  99. notionary/page/content/parser/parsers/table_of_contents.py +7 -3
  100. notionary/page/content/parser/parsers/todo.py +15 -5
  101. notionary/page/content/parser/parsers/toggle.py +15 -5
  102. notionary/page/content/parser/parsers/video.py +7 -2
  103. notionary/page/content/parser/post_processing/handlers/rich_text_length.py +8 -2
  104. notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +8 -2
  105. notionary/page/content/parser/post_processing/service.py +3 -1
  106. notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +21 -7
  107. notionary/page/content/parser/pre_processsing/handlers/indentation.py +11 -4
  108. notionary/page/content/parser/pre_processsing/handlers/video_syntax.py +13 -6
  109. notionary/page/content/parser/service.py +4 -1
  110. notionary/page/content/renderer/context.py +15 -5
  111. notionary/page/content/renderer/factory.py +12 -6
  112. notionary/page/content/renderer/post_processing/handlers/numbered_list.py +19 -9
  113. notionary/page/content/renderer/renderers/audio.py +14 -5
  114. notionary/page/content/renderer/renderers/base.py +3 -3
  115. notionary/page/content/renderer/renderers/bookmark.py +3 -1
  116. notionary/page/content/renderer/renderers/bulleted_list.py +11 -5
  117. notionary/page/content/renderer/renderers/callout.py +19 -7
  118. notionary/page/content/renderer/renderers/captioned_block.py +11 -5
  119. notionary/page/content/renderer/renderers/code.py +6 -2
  120. notionary/page/content/renderer/renderers/column.py +3 -1
  121. notionary/page/content/renderer/renderers/column_list.py +3 -1
  122. notionary/page/content/renderer/renderers/embed.py +3 -1
  123. notionary/page/content/renderer/renderers/equation.py +3 -1
  124. notionary/page/content/renderer/renderers/file.py +14 -5
  125. notionary/page/content/renderer/renderers/file_like_block.py +8 -4
  126. notionary/page/content/renderer/renderers/heading.py +22 -8
  127. notionary/page/content/renderer/renderers/image.py +13 -4
  128. notionary/page/content/renderer/renderers/numbered_list.py +8 -3
  129. notionary/page/content/renderer/renderers/paragraph.py +12 -4
  130. notionary/page/content/renderer/renderers/pdf.py +14 -5
  131. notionary/page/content/renderer/renderers/quote.py +14 -6
  132. notionary/page/content/renderer/renderers/table.py +15 -5
  133. notionary/page/content/renderer/renderers/todo.py +16 -6
  134. notionary/page/content/renderer/renderers/toggle.py +8 -4
  135. notionary/page/content/renderer/renderers/video.py +14 -5
  136. notionary/page/content/renderer/service.py +9 -3
  137. notionary/page/content/service.py +21 -7
  138. notionary/page/content/syntax/definition/__init__.py +11 -0
  139. notionary/page/content/syntax/definition/models.py +57 -0
  140. notionary/page/content/syntax/definition/registry.py +371 -0
  141. notionary/page/content/syntax/prompts/__init__.py +4 -0
  142. notionary/page/content/syntax/prompts/models.py +11 -0
  143. notionary/page/content/syntax/prompts/registry.py +703 -0
  144. notionary/page/page_metadata_update_client.py +12 -4
  145. notionary/page/properties/client.py +45 -15
  146. notionary/page/properties/factory.py +6 -2
  147. notionary/page/properties/service.py +110 -36
  148. notionary/page/service.py +20 -6
  149. notionary/shared/entity/client.py +6 -2
  150. notionary/shared/entity/dto_parsers.py +3 -1
  151. notionary/shared/entity/entity_metadata_update_client.py +9 -3
  152. notionary/shared/entity/service.py +53 -22
  153. notionary/shared/models/file.py +3 -1
  154. notionary/user/base.py +6 -2
  155. notionary/user/bot.py +10 -2
  156. notionary/user/client.py +3 -1
  157. notionary/user/person.py +3 -1
  158. notionary/user/schemas.py +3 -1
  159. notionary/user/service.py +6 -2
  160. notionary/utils/decorators.py +6 -2
  161. notionary/utils/fuzzy.py +6 -2
  162. notionary/utils/mixins/logging.py +3 -1
  163. notionary/utils/pagination.py +14 -4
  164. notionary/workspace/__init__.py +5 -1
  165. notionary/workspace/query/service.py +59 -16
  166. notionary/workspace/service.py +39 -11
  167. {notionary-0.4.0.dist-info → notionary-0.4.1.dist-info}/METADATA +1 -1
  168. notionary-0.4.1.dist-info/RECORD +236 -0
  169. notionary/page/blocks/client.py +0 -1
  170. notionary/page/content/syntax/__init__.py +0 -5
  171. notionary/page/content/syntax/models.py +0 -66
  172. notionary/page/content/syntax/registry.py +0 -371
  173. notionary-0.4.0.dist-info/RECORD +0 -230
  174. /notionary/page/content/syntax/{grammar.py → definition/grammar.py} +0 -0
  175. {notionary-0.4.0.dist-info → notionary-0.4.1.dist-info}/WHEEL +0 -0
  176. {notionary-0.4.0.dist-info → notionary-0.4.1.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 EntityMetadataUpdateClient
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(self, updated_data: NotionEntityUpdateDto) -> NotionPageDto:
16
- updated_data_dict = updated_data.model_dump(exclude_unset=True, exclude_none=True)
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(f"pages/{self._page_id}", data=updated_data_dict)
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(property_type, current_property, value)
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(self, property_name: str, text: str) -> NotionPageDto:
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(self, property_name: str, email: str) -> NotionPageDto:
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(self, property_name: str, phone: str) -> NotionPageDto:
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(self, property_name: str, number: int | float) -> NotionPageDto:
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(self, property_name: str, checked: bool) -> NotionPageDto:
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(self, property_name: str, value: str) -> NotionPageDto:
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(self, property_name: str, values: list[str]) -> NotionPageDto:
79
- return await self._patch_property(property_name, values, PageMultiSelectProperty)
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(self, property_name: str, date_value: str | dict) -> NotionPageDto:
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(self, property_name: str, status: str) -> NotionPageDto:
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(self, property_name: str, relation_ids: str | list[str]) -> NotionPageDto:
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(property_name, relation_ids, PageRelationProperty)
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 = [SelectOption(id="", name=str(item)) for item in value]
130
- return PageMultiSelectProperty(id=property_id, multi_select=multi_select_options)
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(self, page_response: NotionPageDto) -> PagePropertyHandler:
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(page_id=page_response.id),
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 convert_rich_text_to_markdown
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(property_name, PagePeopleProperty)
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(name, PageCreatedTimeProperty)
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(name, PageRelationProperty)
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 = [await NotionPage.from_id(page_id) for page_id in relation_page_ids]
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(name, PageMultiSelectProperty)
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(name, PageCheckboxProperty)
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(name, PageRichTextProperty)
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(name, PagePhoneNumberProperty)
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(self, property_name: str) -> list[str]:
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(self, property_name: str) -> list[str]:
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(self, property_name: str) -> list[str]:
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(self, property_name: str) -> list[str]:
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(title_property_name, 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
- (key for key, prop in self._properties.items() if isinstance(prop, PageTitleProperty)),
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(property_name, text)
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(property_name, url)
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(property_name, email)
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(self, property_name: str, phone_number: str) -> None:
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(property_name, phone_number)
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(self, property_name: str, number: int | float) -> None:
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(property_name, number)
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(property_name, checked)
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(self, property_name: str, date_value: str | dict) -> None:
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(property_name, date_value)
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(self, property_name: str, option_name: str) -> None:
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(property_name, option_name)
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(self, property_name: str, option_names: list[str]) -> None:
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(property_name, option_names)
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(self, property_name: str, status: str) -> None:
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(property_name, status)
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(self, property_name: str, page_titles: list[str]) -> None:
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(property_name, relation_ids)
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) if self._parent_data_source_id else None
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(self, name: str, property_type: type[PagePropertyT]) -> PagePropertyT:
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(*[NotionPage.from_title(title=title) for title in page_titles])
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 convert_rich_text_to_markdown
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(dto)
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(page_id=dto.id, block_client=block_client)
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
- (prop for prop in response.properties.values() if isinstance(prop, PageTitleProperty)),
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(page_id=self._id, text=comment)
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(discussion_id=discussion_id, text=comment)
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 EntityMetadataUpdateClient
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(exclude_unset=True, exclude_none=True)
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 RichTextToMarkdownConverter
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(self, updated_data: NotionEntityUpdateDto) -> EntityResponseDto: ...
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(self, file_upload_id: str) -> EntityResponseDto:
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(self, file_upload_id: str) -> EntityResponseDto:
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