notionary 0.2.26__py3-none-any.whl → 0.2.28__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 (387) hide show
  1. notionary/__init__.py +5 -20
  2. notionary/blocks/client.py +87 -215
  3. notionary/blocks/enums.py +167 -0
  4. notionary/blocks/rich_text/markdown_rich_text_converter.py +266 -0
  5. notionary/blocks/rich_text/models.py +164 -0
  6. notionary/blocks/rich_text/name_id_resolver/__init__.py +11 -0
  7. notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
  8. notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
  9. notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
  10. notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
  11. notionary/blocks/rich_text/rich_text_markdown_converter.py +132 -0
  12. notionary/blocks/rich_text/rich_text_patterns.py +39 -0
  13. notionary/blocks/schemas.py +746 -0
  14. notionary/comments/client.py +52 -187
  15. notionary/comments/factory.py +40 -0
  16. notionary/comments/models.py +5 -127
  17. notionary/comments/schemas.py +240 -0
  18. notionary/comments/service.py +34 -0
  19. notionary/data_source/http/client.py +11 -0
  20. notionary/data_source/http/data_source_instance_client.py +94 -0
  21. notionary/data_source/properties/models.py +406 -0
  22. notionary/data_source/query/builder.py +429 -0
  23. notionary/data_source/query/resolver.py +114 -0
  24. notionary/data_source/query/schema.py +304 -0
  25. notionary/data_source/query/validator.py +73 -0
  26. notionary/data_source/schemas.py +27 -0
  27. notionary/data_source/service.py +353 -0
  28. notionary/database/client.py +30 -135
  29. notionary/database/database_metadata_update_client.py +19 -0
  30. notionary/database/schemas.py +29 -0
  31. notionary/database/service.py +169 -0
  32. notionary/exceptions/__init__.py +33 -0
  33. notionary/exceptions/api.py +41 -0
  34. notionary/exceptions/base.py +2 -0
  35. notionary/exceptions/block_parsing.py +16 -0
  36. notionary/exceptions/data_source/__init__.py +6 -0
  37. notionary/exceptions/data_source/builder.py +182 -0
  38. notionary/exceptions/data_source/properties.py +34 -0
  39. notionary/exceptions/properties.py +58 -0
  40. notionary/exceptions/search.py +33 -0
  41. notionary/file_upload/client.py +18 -30
  42. notionary/file_upload/models.py +7 -8
  43. notionary/file_upload/{notion_file_upload.py → service.py} +29 -64
  44. notionary/http/client.py +205 -0
  45. notionary/http/models.py +49 -0
  46. notionary/page/blocks/client.py +1 -0
  47. notionary/page/content/factory.py +68 -0
  48. notionary/page/content/markdown/__init__.py +5 -0
  49. notionary/page/content/markdown/builder.py +304 -0
  50. notionary/page/content/markdown/nodes/__init__.py +54 -0
  51. notionary/page/content/markdown/nodes/audio.py +23 -0
  52. notionary/page/content/markdown/nodes/base.py +12 -0
  53. notionary/page/content/markdown/nodes/bookmark.py +25 -0
  54. notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
  55. notionary/page/content/markdown/nodes/bulleted_list.py +18 -0
  56. notionary/page/content/markdown/nodes/callout.py +32 -0
  57. notionary/page/content/markdown/nodes/code.py +30 -0
  58. notionary/page/content/markdown/nodes/columns.py +51 -0
  59. notionary/page/content/markdown/nodes/divider.py +14 -0
  60. notionary/page/content/markdown/nodes/embed.py +23 -0
  61. notionary/page/content/markdown/nodes/equation.py +19 -0
  62. notionary/page/content/markdown/nodes/file.py +23 -0
  63. notionary/page/content/markdown/nodes/heading.py +16 -0
  64. notionary/page/content/markdown/nodes/image.py +23 -0
  65. notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
  66. notionary/page/content/markdown/nodes/numbered_list.py +15 -0
  67. notionary/page/content/markdown/nodes/paragraph.py +14 -0
  68. notionary/page/content/markdown/nodes/pdf.py +23 -0
  69. notionary/page/content/markdown/nodes/quote.py +15 -0
  70. notionary/page/content/markdown/nodes/space.py +14 -0
  71. notionary/page/content/markdown/nodes/table.py +45 -0
  72. notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
  73. notionary/page/content/markdown/nodes/todo.py +22 -0
  74. notionary/page/content/markdown/nodes/toggle.py +28 -0
  75. notionary/page/content/markdown/nodes/toggleable_heading.py +35 -0
  76. notionary/page/content/markdown/nodes/video.py +23 -0
  77. notionary/page/content/parser/context.py +49 -0
  78. notionary/page/content/parser/factory.py +219 -0
  79. notionary/page/content/parser/parsers/__init__.py +60 -0
  80. notionary/page/content/parser/parsers/audio.py +40 -0
  81. notionary/page/content/parser/parsers/base.py +30 -0
  82. notionary/page/content/parser/parsers/bookmark.py +33 -0
  83. notionary/page/content/parser/parsers/breadcrumb.py +33 -0
  84. notionary/page/content/parser/parsers/bulleted_list.py +41 -0
  85. notionary/page/content/parser/parsers/callout.py +129 -0
  86. notionary/page/content/parser/parsers/caption.py +55 -0
  87. notionary/page/content/parser/parsers/code.py +81 -0
  88. notionary/page/content/parser/parsers/column.py +117 -0
  89. notionary/page/content/parser/parsers/column_list.py +81 -0
  90. notionary/page/content/parser/parsers/divider.py +33 -0
  91. notionary/page/content/parser/parsers/embed.py +33 -0
  92. notionary/page/content/parser/parsers/equation.py +65 -0
  93. notionary/page/content/parser/parsers/file.py +42 -0
  94. notionary/page/content/parser/parsers/heading.py +58 -0
  95. notionary/page/content/parser/parsers/image.py +42 -0
  96. notionary/page/content/parser/parsers/numbered_list.py +45 -0
  97. notionary/page/content/parser/parsers/paragraph.py +36 -0
  98. notionary/page/content/parser/parsers/pdf.py +42 -0
  99. notionary/page/content/parser/parsers/quote.py +65 -0
  100. notionary/page/content/parser/parsers/space.py +35 -0
  101. notionary/page/content/parser/parsers/table.py +144 -0
  102. notionary/page/content/parser/parsers/table_of_contents.py +32 -0
  103. notionary/page/content/parser/parsers/todo.py +58 -0
  104. notionary/page/content/parser/parsers/toggle.py +127 -0
  105. notionary/page/content/parser/parsers/toggleable_heading.py +150 -0
  106. notionary/page/content/parser/parsers/video.py +42 -0
  107. notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
  108. notionary/page/content/parser/post_processing/handlers/rich_text_length.py +93 -0
  109. notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +93 -0
  110. notionary/page/content/parser/post_processing/port.py +9 -0
  111. notionary/page/content/parser/post_processing/service.py +16 -0
  112. notionary/page/content/parser/pre_processsing/handlers/__init__.py +9 -0
  113. notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +80 -0
  114. notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
  115. notionary/page/content/parser/pre_processsing/handlers/whitespace.py +68 -0
  116. notionary/page/content/parser/pre_processsing/service.py +15 -0
  117. notionary/page/content/parser/service.py +69 -0
  118. notionary/page/content/renderer/context.py +48 -0
  119. notionary/page/content/renderer/factory.py +240 -0
  120. notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
  121. notionary/page/content/renderer/post_processing/handlers/numbered_list_placeholdere.py +62 -0
  122. notionary/page/content/renderer/post_processing/port.py +7 -0
  123. notionary/page/content/renderer/post_processing/service.py +15 -0
  124. notionary/page/content/renderer/renderers/__init__.py +57 -0
  125. notionary/page/content/renderer/renderers/audio.py +31 -0
  126. notionary/page/content/renderer/renderers/base.py +31 -0
  127. notionary/page/content/renderer/renderers/bookmark.py +25 -0
  128. notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
  129. notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
  130. notionary/page/content/renderer/renderers/callout.py +65 -0
  131. notionary/page/content/renderer/renderers/captioned_block.py +58 -0
  132. notionary/page/content/renderer/renderers/code.py +34 -0
  133. notionary/page/content/renderer/renderers/column.py +44 -0
  134. notionary/page/content/renderer/renderers/column_list.py +31 -0
  135. notionary/page/content/renderer/renderers/divider.py +22 -0
  136. notionary/page/content/renderer/renderers/embed.py +25 -0
  137. notionary/page/content/renderer/renderers/equation.py +37 -0
  138. notionary/page/content/renderer/renderers/fallback.py +24 -0
  139. notionary/page/content/renderer/renderers/file.py +40 -0
  140. notionary/page/content/renderer/renderers/heading.py +69 -0
  141. notionary/page/content/renderer/renderers/image.py +31 -0
  142. notionary/page/content/renderer/renderers/numbered_list.py +41 -0
  143. notionary/page/content/renderer/renderers/paragraph.py +40 -0
  144. notionary/page/content/renderer/renderers/pdf.py +31 -0
  145. notionary/page/content/renderer/renderers/quote.py +49 -0
  146. notionary/page/content/renderer/renderers/table.py +115 -0
  147. notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
  148. notionary/page/content/renderer/renderers/table_row.py +17 -0
  149. notionary/page/content/renderer/renderers/todo.py +56 -0
  150. notionary/page/content/renderer/renderers/toggle.py +53 -0
  151. notionary/page/content/renderer/renderers/toggleable_heading.py +78 -0
  152. notionary/page/content/renderer/renderers/video.py +31 -0
  153. notionary/page/content/renderer/service.py +50 -0
  154. notionary/page/content/service.py +65 -0
  155. notionary/page/content/syntax/models.py +68 -0
  156. notionary/page/content/syntax/service.py +453 -0
  157. notionary/page/page_context.py +7 -16
  158. notionary/page/page_http_client.py +15 -0
  159. notionary/page/page_metadata_update_client.py +19 -0
  160. notionary/page/properties/client.py +144 -0
  161. notionary/page/properties/factory.py +26 -0
  162. notionary/page/properties/models.py +307 -0
  163. notionary/page/properties/service.py +257 -0
  164. notionary/page/schemas.py +13 -0
  165. notionary/page/service.py +222 -0
  166. notionary/shared/entity/client.py +29 -0
  167. notionary/shared/entity/dto_parsers.py +53 -0
  168. notionary/shared/entity/entity_metadata_update_client.py +41 -0
  169. notionary/shared/entity/schemas.py +45 -0
  170. notionary/shared/entity/service.py +171 -0
  171. notionary/shared/models/cover.py +20 -0
  172. notionary/shared/models/file.py +21 -0
  173. notionary/shared/models/icon.py +28 -0
  174. notionary/shared/models/parent.py +41 -0
  175. notionary/shared/properties/type.py +30 -0
  176. notionary/user/__init__.py +4 -8
  177. notionary/user/base.py +89 -0
  178. notionary/user/bot.py +70 -0
  179. notionary/user/client.py +22 -111
  180. notionary/user/person.py +41 -0
  181. notionary/user/schemas.py +67 -0
  182. notionary/user/service.py +65 -0
  183. notionary/utils/async_retry.py +39 -0
  184. notionary/utils/date.py +51 -0
  185. notionary/utils/fuzzy.py +56 -0
  186. notionary/{util/logging_mixin.py → utils/mixins/logging.py} +4 -16
  187. notionary/utils/pagination.py +50 -0
  188. notionary/utils/singleton.py +13 -0
  189. notionary/utils/uuid_utils.py +20 -0
  190. notionary/workspace/__init__.py +3 -0
  191. notionary/workspace/client.py +62 -0
  192. notionary/workspace/query/builder.py +60 -0
  193. notionary/workspace/query/models.py +60 -0
  194. notionary/workspace/query/service.py +93 -0
  195. notionary/workspace/schemas.py +21 -0
  196. notionary/workspace/service.py +116 -0
  197. {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info}/METADATA +54 -49
  198. notionary-0.2.28.dist-info/RECORD +200 -0
  199. {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info}/WHEEL +1 -1
  200. {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info/licenses}/LICENSE +9 -9
  201. notionary/base_notion_client.py +0 -219
  202. notionary/blocks/__init__.py +0 -5
  203. notionary/blocks/_bootstrap.py +0 -271
  204. notionary/blocks/audio/__init__.py +0 -11
  205. notionary/blocks/audio/audio_element.py +0 -158
  206. notionary/blocks/audio/audio_markdown_node.py +0 -24
  207. notionary/blocks/audio/audio_models.py +0 -10
  208. notionary/blocks/base_block_element.py +0 -42
  209. notionary/blocks/bookmark/__init__.py +0 -12
  210. notionary/blocks/bookmark/bookmark_element.py +0 -83
  211. notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
  212. notionary/blocks/bookmark/bookmark_models.py +0 -15
  213. notionary/blocks/breadcrumbs/__init__.py +0 -15
  214. notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
  215. notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
  216. notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
  217. notionary/blocks/bulleted_list/__init__.py +0 -15
  218. notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
  219. notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
  220. notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
  221. notionary/blocks/callout/__init__.py +0 -12
  222. notionary/blocks/callout/callout_element.py +0 -99
  223. notionary/blocks/callout/callout_markdown_node.py +0 -19
  224. notionary/blocks/callout/callout_models.py +0 -33
  225. notionary/blocks/child_database/__init__.py +0 -14
  226. notionary/blocks/child_database/child_database_element.py +0 -59
  227. notionary/blocks/child_database/child_database_models.py +0 -12
  228. notionary/blocks/child_page/__init__.py +0 -9
  229. notionary/blocks/child_page/child_page_element.py +0 -94
  230. notionary/blocks/child_page/child_page_models.py +0 -12
  231. notionary/blocks/code/__init__.py +0 -11
  232. notionary/blocks/code/code_element.py +0 -149
  233. notionary/blocks/code/code_markdown_node.py +0 -80
  234. notionary/blocks/code/code_models.py +0 -94
  235. notionary/blocks/column/__init__.py +0 -25
  236. notionary/blocks/column/column_element.py +0 -65
  237. notionary/blocks/column/column_list_element.py +0 -52
  238. notionary/blocks/column/column_list_markdown_node.py +0 -34
  239. notionary/blocks/column/column_markdown_node.py +0 -42
  240. notionary/blocks/column/column_models.py +0 -26
  241. notionary/blocks/divider/__init__.py +0 -12
  242. notionary/blocks/divider/divider_element.py +0 -41
  243. notionary/blocks/divider/divider_markdown_node.py +0 -11
  244. notionary/blocks/divider/divider_models.py +0 -12
  245. notionary/blocks/embed/__init__.py +0 -12
  246. notionary/blocks/embed/embed_element.py +0 -98
  247. notionary/blocks/embed/embed_markdown_node.py +0 -19
  248. notionary/blocks/embed/embed_models.py +0 -14
  249. notionary/blocks/equation/__init__.py +0 -13
  250. notionary/blocks/equation/equation_element.py +0 -133
  251. notionary/blocks/equation/equation_element_markdown_node.py +0 -23
  252. notionary/blocks/equation/equation_models.py +0 -11
  253. notionary/blocks/file/__init__.py +0 -23
  254. notionary/blocks/file/file_element.py +0 -133
  255. notionary/blocks/file/file_element_markdown_node.py +0 -24
  256. notionary/blocks/file/file_element_models.py +0 -39
  257. notionary/blocks/heading/__init__.py +0 -19
  258. notionary/blocks/heading/heading_element.py +0 -112
  259. notionary/blocks/heading/heading_markdown_node.py +0 -16
  260. notionary/blocks/heading/heading_models.py +0 -29
  261. notionary/blocks/image_block/__init__.py +0 -11
  262. notionary/blocks/image_block/image_element.py +0 -130
  263. notionary/blocks/image_block/image_markdown_node.py +0 -25
  264. notionary/blocks/image_block/image_models.py +0 -10
  265. notionary/blocks/markdown/markdown_builder.py +0 -525
  266. notionary/blocks/markdown/markdown_document_model.py +0 -0
  267. notionary/blocks/markdown/markdown_node.py +0 -25
  268. notionary/blocks/mixins/captions/__init__.py +0 -4
  269. notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
  270. notionary/blocks/mixins/captions/caption_mixin.py +0 -92
  271. notionary/blocks/mixins/file_upload/__init__.py +0 -3
  272. notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
  273. notionary/blocks/models.py +0 -174
  274. notionary/blocks/numbered_list/__init__.py +0 -16
  275. notionary/blocks/numbered_list/numbered_list_element.py +0 -65
  276. notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
  277. notionary/blocks/numbered_list/numbered_list_models.py +0 -17
  278. notionary/blocks/paragraph/__init__.py +0 -15
  279. notionary/blocks/paragraph/paragraph_element.py +0 -58
  280. notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
  281. notionary/blocks/paragraph/paragraph_models.py +0 -16
  282. notionary/blocks/pdf/__init__.py +0 -11
  283. notionary/blocks/pdf/pdf_element.py +0 -146
  284. notionary/blocks/pdf/pdf_markdown_node.py +0 -24
  285. notionary/blocks/pdf/pdf_models.py +0 -11
  286. notionary/blocks/quote/__init__.py +0 -14
  287. notionary/blocks/quote/quote_element.py +0 -75
  288. notionary/blocks/quote/quote_markdown_node.py +0 -16
  289. notionary/blocks/quote/quote_models.py +0 -18
  290. notionary/blocks/registry/__init__.py +0 -3
  291. notionary/blocks/registry/block_registry.py +0 -150
  292. notionary/blocks/rich_text/__init__.py +0 -33
  293. notionary/blocks/rich_text/rich_text_models.py +0 -221
  294. notionary/blocks/rich_text/text_inline_formatter.py +0 -456
  295. notionary/blocks/syntax_prompt_builder.py +0 -137
  296. notionary/blocks/table/__init__.py +0 -19
  297. notionary/blocks/table/table_element.py +0 -225
  298. notionary/blocks/table/table_markdown_node.py +0 -42
  299. notionary/blocks/table/table_models.py +0 -28
  300. notionary/blocks/table_of_contents/__init__.py +0 -17
  301. notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
  302. notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
  303. notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
  304. notionary/blocks/todo/__init__.py +0 -12
  305. notionary/blocks/todo/todo_element.py +0 -81
  306. notionary/blocks/todo/todo_markdown_node.py +0 -21
  307. notionary/blocks/todo/todo_models.py +0 -18
  308. notionary/blocks/toggle/__init__.py +0 -12
  309. notionary/blocks/toggle/toggle_element.py +0 -112
  310. notionary/blocks/toggle/toggle_markdown_node.py +0 -31
  311. notionary/blocks/toggle/toggle_models.py +0 -17
  312. notionary/blocks/toggleable_heading/__init__.py +0 -11
  313. notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
  314. notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
  315. notionary/blocks/types.py +0 -130
  316. notionary/blocks/video/__init__.py +0 -11
  317. notionary/blocks/video/video_element.py +0 -187
  318. notionary/blocks/video/video_element_models.py +0 -10
  319. notionary/blocks/video/video_markdown_node.py +0 -26
  320. notionary/comments/__init__.py +0 -26
  321. notionary/database/__init__.py +0 -4
  322. notionary/database/database.py +0 -480
  323. notionary/database/database_filter_builder.py +0 -173
  324. notionary/database/database_provider.py +0 -227
  325. notionary/database/exceptions.py +0 -13
  326. notionary/database/factory.py +0 -0
  327. notionary/database/models.py +0 -337
  328. notionary/database/notion_database.py +0 -487
  329. notionary/file_upload/__init__.py +0 -7
  330. notionary/page/client.py +0 -124
  331. notionary/page/markdown_whitespace_processor.py +0 -129
  332. notionary/page/models.py +0 -322
  333. notionary/page/notion_page.py +0 -674
  334. notionary/page/page_content_deleting_service.py +0 -117
  335. notionary/page/page_content_writer.py +0 -80
  336. notionary/page/property_formatter.py +0 -99
  337. notionary/page/reader/handler/__init__.py +0 -19
  338. notionary/page/reader/handler/base_block_renderer.py +0 -44
  339. notionary/page/reader/handler/block_processing_context.py +0 -35
  340. notionary/page/reader/handler/block_rendering_context.py +0 -48
  341. notionary/page/reader/handler/column_list_renderer.py +0 -51
  342. notionary/page/reader/handler/column_renderer.py +0 -60
  343. notionary/page/reader/handler/equation_renderer.py +0 -0
  344. notionary/page/reader/handler/line_renderer.py +0 -73
  345. notionary/page/reader/handler/numbered_list_renderer.py +0 -85
  346. notionary/page/reader/handler/toggle_renderer.py +0 -69
  347. notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
  348. notionary/page/reader/page_content_retriever.py +0 -81
  349. notionary/page/search_filter_builder.py +0 -132
  350. notionary/page/utils.py +0 -60
  351. notionary/page/writer/handler/__init__.py +0 -24
  352. notionary/page/writer/handler/code_handler.py +0 -72
  353. notionary/page/writer/handler/column_handler.py +0 -141
  354. notionary/page/writer/handler/column_list_handler.py +0 -139
  355. notionary/page/writer/handler/equation_handler.py +0 -74
  356. notionary/page/writer/handler/line_handler.py +0 -35
  357. notionary/page/writer/handler/line_processing_context.py +0 -54
  358. notionary/page/writer/handler/regular_line_handler.py +0 -86
  359. notionary/page/writer/handler/table_handler.py +0 -66
  360. notionary/page/writer/handler/toggle_handler.py +0 -159
  361. notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
  362. notionary/page/writer/markdown_to_notion_converter.py +0 -139
  363. notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
  364. notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
  365. notionary/page/writer/notion_text_length_processor.py +0 -150
  366. notionary/schemas/__init__.py +0 -3
  367. notionary/schemas/base.py +0 -73
  368. notionary/shared/__init__.py +0 -3
  369. notionary/shared/name_to_id_resolver.py +0 -203
  370. notionary/telemetry/__init__.py +0 -19
  371. notionary/telemetry/service.py +0 -136
  372. notionary/telemetry/views.py +0 -73
  373. notionary/user/base_notion_user.py +0 -53
  374. notionary/user/models.py +0 -84
  375. notionary/user/notion_bot_user.py +0 -226
  376. notionary/user/notion_user.py +0 -255
  377. notionary/user/notion_user_manager.py +0 -101
  378. notionary/util/__init__.py +0 -15
  379. notionary/util/concurrency_limiter.py +0 -0
  380. notionary/util/factory_decorator.py +0 -0
  381. notionary/util/factory_only.py +0 -37
  382. notionary/util/fuzzy.py +0 -75
  383. notionary/util/page_id_utils.py +0 -27
  384. notionary/util/singleton.py +0 -18
  385. notionary/util/singleton_metaclass.py +0 -22
  386. notionary/workspace.py +0 -105
  387. notionary-0.2.26.dist-info/RECORD +0 -202
@@ -1,12 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Optional
4
- from dataclasses import dataclass
5
3
  from contextvars import ContextVar
4
+ from dataclasses import dataclass
5
+ from typing import TYPE_CHECKING
6
6
 
7
7
  if TYPE_CHECKING:
8
- from notionary.database.client import NotionDatabaseClient
9
- from notionary.file_upload import NotionFileUploadClient
8
+ from notionary.file_upload import FileUploadHttpClient
10
9
 
11
10
 
12
11
  @dataclass(frozen=True)
@@ -14,35 +13,27 @@ class PageContextProvider:
14
13
  """Context object that provides dependencies for block conversion operations."""
15
14
 
16
15
  page_id: str
17
- database_client: NotionDatabaseClient
18
- file_upload_client: NotionFileUploadClient
16
+ file_upload_client: FileUploadHttpClient
19
17
 
20
18
 
21
19
  # Context variable
22
- _page_context: ContextVar[Optional[PageContextProvider]] = ContextVar(
23
- "page_context", default=None
24
- )
20
+ _page_context: ContextVar[PageContextProvider | None] = ContextVar("page_context", default=None)
25
21
 
26
22
 
27
23
  def get_page_context() -> PageContextProvider:
28
24
  """Get current page context or raise if not available."""
29
25
  context = _page_context.get()
30
26
  if context is None:
31
- raise RuntimeError(
32
- "No page context available. Use 'async with page_context(...)'"
33
- )
27
+ raise RuntimeError("No page context available. Use 'async with page_context(...)'")
34
28
  return context
35
29
 
36
30
 
37
31
  class page_context:
38
- """Async-only context manager for page operations."""
39
-
40
- def __init__(self, provider: PageContextProvider):
32
+ def __init__(self, provider: PageContextProvider) -> None:
41
33
  self.provider = provider
42
34
  self._token = None
43
35
 
44
36
  def _set_context(self) -> PageContextProvider:
45
- """Helper to set context and return provider."""
46
37
  self._token = _page_context.set(self.provider)
47
38
  return self.provider
48
39
 
@@ -0,0 +1,15 @@
1
+ from notionary.http.client import NotionHttpClient
2
+ from notionary.page.schemas import NotionPageDto
3
+
4
+
5
+ class NotionPageHttpClient(NotionHttpClient):
6
+ def __init__(
7
+ self,
8
+ page_id: str,
9
+ ):
10
+ super().__init__()
11
+ self._page_id = page_id
12
+
13
+ async def get_page(self) -> NotionPageDto:
14
+ response = await self.get(f"pages/{self._page_id}")
15
+ return NotionPageDto.model_validate(response)
@@ -0,0 +1,19 @@
1
+ from typing import override
2
+
3
+ from notionary.http.client import NotionHttpClient
4
+ from notionary.page.schemas import NotionPageDto
5
+ from notionary.shared.entity.entity_metadata_update_client import EntityMetadataUpdateClient
6
+ from notionary.shared.entity.schemas import NotionEntityUpdateDto
7
+
8
+
9
+ class PageMetadataUpdateClient(NotionHttpClient, EntityMetadataUpdateClient):
10
+ def __init__(self, page_id: str, timeout: int = 30) -> None:
11
+ super().__init__(timeout)
12
+ self._page_id = page_id
13
+
14
+ @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
+
18
+ response_dict = await self.patch(f"pages/{self._page_id}", data=updated_data_dict)
19
+ return NotionPageDto.model_validate(response_dict)
@@ -0,0 +1,144 @@
1
+ from typing import Any
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from notionary.blocks.rich_text.models import RichText
6
+ from notionary.http.client import NotionHttpClient
7
+ from notionary.page.properties.models import (
8
+ DateValue,
9
+ PageCheckboxProperty,
10
+ PageDateProperty,
11
+ PageEmailProperty,
12
+ PageMultiSelectProperty,
13
+ PageNumberProperty,
14
+ PagePhoneNumberProperty,
15
+ PagePropertyT,
16
+ PageRelationProperty,
17
+ PageRichTextProperty,
18
+ PageSelectProperty,
19
+ PageStatusProperty,
20
+ PageTitleProperty,
21
+ PageURLProperty,
22
+ RelationItem,
23
+ SelectOption,
24
+ StatusOption,
25
+ )
26
+ from notionary.page.schemas import NotionPageDto, PgePropertiesUpdateDto
27
+
28
+
29
+ class PagePropertyHttpClient(NotionHttpClient):
30
+ def __init__(self, page_id: str) -> None:
31
+ super().__init__()
32
+ self._page_id = page_id
33
+
34
+ async def patch_page(self, data: BaseModel) -> NotionPageDto:
35
+ data_dict = data.model_dump(exclude_unset=True, exclude_none=True)
36
+
37
+ result_dict = await self.patch(f"pages/{self._page_id}", data=data_dict)
38
+ return NotionPageDto.model_validate(result_dict)
39
+
40
+ async def _patch_property(
41
+ self,
42
+ property_name: str,
43
+ value: Any,
44
+ property_type: type[PagePropertyT],
45
+ current_property: PagePropertyT | None = None,
46
+ ) -> NotionPageDto:
47
+ updated_property = self._create_updated_property(property_type, current_property, value)
48
+
49
+ properties = {property_name: updated_property}
50
+ update_dto = PgePropertiesUpdateDto(properties=properties)
51
+
52
+ return await self.patch_page(update_dto)
53
+
54
+ async def patch_title(self, title: str) -> NotionPageDto:
55
+ return await self._patch_property("title", title, PageTitleProperty)
56
+
57
+ async def patch_rich_text_property(self, property_name: str, text: str) -> NotionPageDto:
58
+ return await self._patch_property(property_name, text, PageRichTextProperty)
59
+
60
+ async def patch_url_property(self, property_name: str, url: str) -> NotionPageDto:
61
+ return await self._patch_property(property_name, url, PageURLProperty)
62
+
63
+ async def patch_email_property(self, property_name: str, email: str) -> NotionPageDto:
64
+ return await self._patch_property(property_name, email, PageEmailProperty)
65
+
66
+ async def patch_phone_property(self, property_name: str, phone: str) -> NotionPageDto:
67
+ return await self._patch_property(property_name, phone, PagePhoneNumberProperty)
68
+
69
+ async def patch_number_property(self, property_name: str, number: int | float) -> NotionPageDto:
70
+ return await self._patch_property(property_name, number, PageNumberProperty)
71
+
72
+ async def patch_checkbox_property(self, property_name: str, checked: bool) -> NotionPageDto:
73
+ return await self._patch_property(property_name, checked, PageCheckboxProperty)
74
+
75
+ async def patch_select_property(self, property_name: str, value: str) -> NotionPageDto:
76
+ return await self._patch_property(property_name, value, PageSelectProperty)
77
+
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)
80
+
81
+ async def patch_date_property(self, property_name: str, date_value: str | dict) -> NotionPageDto:
82
+ return await self._patch_property(property_name, date_value, PageDateProperty)
83
+
84
+ async def patch_status_property(self, property_name: str, status: str) -> NotionPageDto:
85
+ return await self._patch_property(property_name, status, PageStatusProperty)
86
+
87
+ async def patch_relation_property(self, property_name: str, relation_ids: str | list[str]) -> NotionPageDto:
88
+ if isinstance(relation_ids, str):
89
+ relation_ids = [relation_ids]
90
+ return await self._patch_property(property_name, relation_ids, PageRelationProperty)
91
+
92
+ # TODO: Fix this shit here
93
+ def _create_updated_property(
94
+ self,
95
+ property_type: type[PagePropertyT],
96
+ current_property: PagePropertyT | None,
97
+ value: Any,
98
+ ) -> PagePropertyT:
99
+ """
100
+ Creates an updated property instance based on the property type and new value.
101
+ """
102
+ # Get the property ID from the current property if it exists
103
+ property_id = current_property.id if current_property else ""
104
+
105
+ if property_type == PageTitleProperty:
106
+ return PageTitleProperty(
107
+ id=property_id,
108
+ title=[RichText(type="text", text={"content": str(value)})],
109
+ )
110
+ elif property_type == PageRichTextProperty:
111
+ return PageRichTextProperty(
112
+ id=property_id,
113
+ rich_text=[RichText(type="text", text={"content": str(value)})],
114
+ )
115
+ elif property_type == PageURLProperty:
116
+ return PageURLProperty(id=property_id, url=str(value))
117
+ elif property_type == PageEmailProperty:
118
+ return PageEmailProperty(id=property_id, email=str(value))
119
+ elif property_type == PagePhoneNumberProperty:
120
+ return PagePhoneNumberProperty(id=property_id, phone_number=str(value))
121
+ elif property_type == PageNumberProperty:
122
+ return PageNumberProperty(id=property_id, number=float(value))
123
+ elif property_type == PageCheckboxProperty:
124
+ return PageCheckboxProperty(id=property_id, checkbox=bool(value))
125
+ elif property_type == PageSelectProperty:
126
+ select_option = SelectOption(id="", name=str(value))
127
+ return PageSelectProperty(id=property_id, select=select_option)
128
+ 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)
131
+ elif property_type == PageDateProperty:
132
+ if isinstance(value, dict) and "start" in value:
133
+ date_value = DateValue(**value)
134
+ else:
135
+ date_value = DateValue(start=str(value))
136
+ return PageDateProperty(id=property_id, date=date_value)
137
+ elif property_type == PageStatusProperty:
138
+ status_option = StatusOption(id="", name=str(value))
139
+ return PageStatusProperty(id=property_id, status=status_option)
140
+ elif property_type == PageRelationProperty:
141
+ relation_items = [RelationItem(id=str(item)) for item in value]
142
+ return PageRelationProperty(id=property_id, relation=relation_items)
143
+ else:
144
+ raise ValueError(f"Unsupported property type: {property_type}")
@@ -0,0 +1,26 @@
1
+ from typing import cast
2
+
3
+ from notionary.page.properties.client import PagePropertyHttpClient
4
+ from notionary.page.properties.service import PagePropertyHandler
5
+ from notionary.page.schemas import NotionPageDto
6
+ from notionary.shared.models.parent import DataSourceParent, ParentType
7
+
8
+
9
+ class PagePropertyHandlerFactory:
10
+ def create_from_page_response(self, page_response: NotionPageDto) -> PagePropertyHandler:
11
+ return PagePropertyHandler(
12
+ properties=page_response.properties,
13
+ parent_type=page_response.parent.type,
14
+ page_url=page_response.url,
15
+ page_property_http_client=self._create_http_client(page_id=page_response.id),
16
+ parent_data_source=self._extract_parent_data_source_id(page_response),
17
+ )
18
+
19
+ def _create_http_client(self, page_id: str) -> PagePropertyHttpClient:
20
+ return PagePropertyHttpClient(page_id=page_id)
21
+
22
+ def _extract_parent_data_source_id(self, response: NotionPageDto) -> str | None:
23
+ if response.parent.type != ParentType.DATA_SOURCE_ID:
24
+ return None
25
+ data_source_parent = cast(DataSourceParent, response.parent)
26
+ return data_source_parent.data_source_id if data_source_parent else None
@@ -0,0 +1,307 @@
1
+ from enum import StrEnum
2
+ from typing import Annotated, Any, Literal, TypeVar
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+ from notionary.blocks.rich_text.models import RichText
7
+ from notionary.shared.properties.type import PropertyType
8
+ from notionary.user.schemas import PersonUserResponseDto, UserResponseDto
9
+
10
+ # ============================================================================
11
+ # Base Models
12
+ # ============================================================================
13
+
14
+
15
+ class PageProperty(BaseModel):
16
+ id: str
17
+ type: str
18
+
19
+
20
+ class StatusOption(BaseModel):
21
+ id: str
22
+ name: str
23
+
24
+
25
+ class SelectOption(BaseModel):
26
+ id: str
27
+ name: str
28
+
29
+
30
+ class RelationItem(BaseModel):
31
+ id: str
32
+
33
+
34
+ class DateValue(BaseModel):
35
+ start: str
36
+ end: str | None = None
37
+ time_zone: str | None = None
38
+
39
+
40
+ # ============================================================================
41
+ # File Models
42
+ # ============================================================================
43
+
44
+
45
+ class FileType(StrEnum):
46
+ EXTERNAL = "external"
47
+ FILE = "file"
48
+
49
+
50
+ class ExternalFile(BaseModel):
51
+ """External file hosted outside of Notion."""
52
+
53
+ url: str
54
+
55
+
56
+ class NotionFile(BaseModel):
57
+ """File uploaded to Notion with expiration."""
58
+
59
+ url: str
60
+ expiry_time: str
61
+
62
+
63
+ class FileObject(BaseModel):
64
+ """File object can be external or uploaded to Notion."""
65
+
66
+ name: str
67
+ type: FileType
68
+ external: ExternalFile | None = None
69
+ file: NotionFile | None = None
70
+
71
+
72
+ # ============================================================================
73
+ # Formula Models
74
+ # ============================================================================
75
+
76
+
77
+ class FormulaValueType(StrEnum):
78
+ BOOLEAN = "boolean"
79
+ DATE = "date"
80
+ NUMBER = "number"
81
+ STRING = "string"
82
+
83
+
84
+ class FormulaValue(BaseModel):
85
+ type: FormulaValueType
86
+ boolean: bool | None = None
87
+ date: DateValue | None = None
88
+ number: float | None = None
89
+ string: str | None = None
90
+
91
+
92
+ # ============================================================================
93
+ # Rollup Models
94
+ # ============================================================================
95
+
96
+
97
+ class RollupValueType(StrEnum):
98
+ NUMBER = "number"
99
+ DATE = "date"
100
+ ARRAY = "array"
101
+ INCOMPLETE = "incomplete"
102
+ UNSUPPORTED = "unsupported"
103
+
104
+
105
+ class RollupValue(BaseModel):
106
+ type: RollupValueType
107
+ function: str # e.g., "sum", "count", "average", "max", "min", etc.
108
+ number: float | None = None
109
+ date: DateValue | None = None
110
+ array: list[Any] | None = None
111
+
112
+
113
+ # ============================================================================
114
+ # Unique ID Models
115
+ # ============================================================================
116
+
117
+
118
+ class UniqueIdValue(BaseModel):
119
+ number: int # Auto-incrementing count
120
+ prefix: str | None = None # Optional prefix like "RL"
121
+
122
+
123
+ # ============================================================================
124
+ # Verification Models
125
+ # ============================================================================
126
+
127
+
128
+ class VerificationState(StrEnum):
129
+ VERIFIED = "verified"
130
+ UNVERIFIED = "unverified"
131
+
132
+
133
+ class VerificationValue(BaseModel):
134
+ state: VerificationState
135
+ verified_by: UserResponseDto | None = None
136
+ date: DateValue | None = None # start = verification date, end = expiration
137
+
138
+
139
+ # ============================================================================
140
+ # Page Property Classes
141
+ # ============================================================================
142
+
143
+
144
+ class PageStatusProperty(PageProperty):
145
+ type: Literal[PropertyType.STATUS] = PropertyType.STATUS
146
+ status: StatusOption | None = None
147
+ options: list[StatusOption] = Field(default_factory=list)
148
+
149
+ @property
150
+ def option_names(self) -> list[str]:
151
+ return [option.name for option in self.options]
152
+
153
+
154
+ class PageRelationProperty(PageProperty):
155
+ type: Literal[PropertyType.RELATION] = PropertyType.RELATION
156
+ relation: list[RelationItem] = Field(default_factory=list)
157
+ has_more: bool = False
158
+
159
+
160
+ class PageURLProperty(PageProperty):
161
+ type: Literal[PropertyType.URL] = PropertyType.URL
162
+ url: str | None = None
163
+
164
+
165
+ class PageRichTextProperty(PageProperty):
166
+ type: Literal[PropertyType.RICH_TEXT] = PropertyType.RICH_TEXT
167
+ rich_text: list[RichText] = Field(default_factory=list)
168
+
169
+
170
+ class PageMultiSelectProperty(PageProperty):
171
+ type: Literal[PropertyType.MULTI_SELECT] = PropertyType.MULTI_SELECT
172
+ multi_select: list[SelectOption] = Field(default_factory=list)
173
+ options: list[SelectOption] = Field(default_factory=list)
174
+
175
+ @property
176
+ def option_names(self) -> list[str]:
177
+ return [option.name for option in self.options]
178
+
179
+
180
+ class PageSelectProperty(PageProperty):
181
+ type: Literal[PropertyType.SELECT] = PropertyType.SELECT
182
+ select: SelectOption | None = None
183
+ options: list[SelectOption] = Field(default_factory=list)
184
+
185
+ @property
186
+ def option_names(self) -> list[str]:
187
+ return [option.name for option in self.options]
188
+
189
+
190
+ class PagePeopleProperty(PageProperty):
191
+ type: Literal[PropertyType.PEOPLE] = PropertyType.PEOPLE
192
+ people: list[PersonUserResponseDto] = Field(default_factory=list)
193
+
194
+
195
+ class PageDateProperty(PageProperty):
196
+ type: Literal[PropertyType.DATE] = PropertyType.DATE
197
+ date: DateValue | None = None
198
+
199
+
200
+ class PageTitleProperty(PageProperty):
201
+ type: Literal[PropertyType.TITLE] = PropertyType.TITLE
202
+ title: list[RichText] = Field(default_factory=list)
203
+
204
+
205
+ class PageNumberProperty(PageProperty):
206
+ type: Literal[PropertyType.NUMBER] = PropertyType.NUMBER
207
+ number: float | None = None
208
+
209
+
210
+ class PageCheckboxProperty(PageProperty):
211
+ type: Literal[PropertyType.CHECKBOX] = PropertyType.CHECKBOX
212
+ checkbox: bool = False
213
+
214
+
215
+ class PageEmailProperty(PageProperty):
216
+ type: Literal[PropertyType.EMAIL] = PropertyType.EMAIL
217
+ email: str | None = None
218
+
219
+
220
+ class PagePhoneNumberProperty(PageProperty):
221
+ type: Literal[PropertyType.PHONE_NUMBER] = PropertyType.PHONE_NUMBER
222
+ phone_number: str | None = None
223
+
224
+
225
+ class PageCreatedTimeProperty(PageProperty):
226
+ type: Literal[PropertyType.CREATED_TIME] = PropertyType.CREATED_TIME
227
+ created_time: str # ISO 8601 datetime - read-only
228
+
229
+
230
+ class PageLastEditedTimeProperty(PageProperty):
231
+ type: Literal[PropertyType.LAST_EDITED_TIME] = PropertyType.LAST_EDITED_TIME
232
+ last_edited_time: str # ISO 8601 datetime - read-only
233
+
234
+
235
+ class PageCreatedByProperty(PageProperty):
236
+ type: Literal[PropertyType.CREATED_BY] = PropertyType.CREATED_BY
237
+ created_by: UserResponseDto # User object - read-only
238
+
239
+
240
+ class PageLastEditedByProperty(PageProperty):
241
+ type: Literal[PropertyType.LAST_EDITED_BY] = PropertyType.LAST_EDITED_BY
242
+ last_edited_by: UserResponseDto # User object - read-only
243
+
244
+
245
+ class PageFilesProperty(PageProperty):
246
+ type: Literal[PropertyType.FILES] = PropertyType.FILES
247
+ files: list[FileObject] = Field(default_factory=list)
248
+
249
+
250
+ class PageFormulaProperty(PageProperty):
251
+ type: Literal[PropertyType.FORMULA] = PropertyType.FORMULA
252
+ formula: FormulaValue
253
+
254
+
255
+ class PageRollupProperty(PageProperty):
256
+ type: Literal[PropertyType.ROLLUP] = PropertyType.ROLLUP
257
+ rollup: RollupValue
258
+
259
+
260
+ class PageUniqueIdProperty(PageProperty):
261
+ type: Literal[PropertyType.UNIQUE_ID] = PropertyType.UNIQUE_ID
262
+ unique_id: UniqueIdValue
263
+
264
+
265
+ class PageVerificationProperty(PageProperty):
266
+ type: Literal[PropertyType.VERIFICATION] = PropertyType.VERIFICATION
267
+ verification: VerificationValue
268
+
269
+
270
+ class PageButtonProperty(PageProperty):
271
+ type: Literal[PropertyType.BUTTON] = PropertyType.BUTTON
272
+ button: dict[str, Any] = Field(default_factory=dict)
273
+
274
+
275
+ # ============================================================================
276
+ # Discriminated Union
277
+ # ============================================================================
278
+
279
+
280
+ DiscriminatedPageProperty = Annotated[
281
+ PageStatusProperty
282
+ | PageRelationProperty
283
+ | PageURLProperty
284
+ | PageRichTextProperty
285
+ | PageMultiSelectProperty
286
+ | PageSelectProperty
287
+ | PagePeopleProperty
288
+ | PageDateProperty
289
+ | PageTitleProperty
290
+ | PageNumberProperty
291
+ | PageCheckboxProperty
292
+ | PageEmailProperty
293
+ | PagePhoneNumberProperty
294
+ | PageCreatedTimeProperty
295
+ | PageLastEditedTimeProperty
296
+ | PageCreatedByProperty
297
+ | PageLastEditedByProperty
298
+ | PageFilesProperty
299
+ | PageFormulaProperty
300
+ | PageRollupProperty
301
+ | PageUniqueIdProperty
302
+ | PageVerificationProperty
303
+ | PageButtonProperty,
304
+ Field(discriminator="type"),
305
+ ]
306
+
307
+ PagePropertyT = TypeVar("PagePropertyT", bound=PageProperty)