notionary 0.2.27__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.27.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.27.dist-info → notionary-0.2.28.dist-info}/WHEEL +1 -1
  200. {notionary-0.2.27.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 -712
  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.27.dist-info/RECORD +0 -202
notionary/__init__.py CHANGED
@@ -1,22 +1,7 @@
1
- from notionary.blocks import bootstrap_blocks
2
-
3
- bootstrap_blocks()
4
-
5
- from .database import DatabaseFilterBuilder, NotionDatabase
6
- from .file_upload import NotionFileUpload
7
- from .blocks.markdown.markdown_builder import MarkdownBuilder
8
- from .page.notion_page import NotionPage
9
- from .user import NotionBotUser, NotionUser, NotionUserManager
1
+ from .data_source.service import NotionDataSource
2
+ from .database.service import NotionDatabase
3
+ from .page.content.markdown.builder import MarkdownBuilder
4
+ from .page.service import NotionPage
10
5
  from .workspace import NotionWorkspace
11
6
 
12
- __all__ = [
13
- "NotionDatabase",
14
- "DatabaseFilterBuilder",
15
- "NotionPage",
16
- "NotionWorkspace",
17
- "NotionUser",
18
- "NotionUserManager",
19
- "NotionBotUser",
20
- "NotionFileUpload",
21
- "MarkdownBuilder",
22
- ]
7
+ __all__ = ["MarkdownBuilder", "NotionDataSource", "NotionDatabase", "NotionPage", "NotionWorkspace", "NotionWorkspace"]
@@ -1,65 +1,42 @@
1
- from typing import Any, Optional
1
+ from typing import Any
2
2
 
3
- from notionary.base_notion_client import BaseNotionClient
4
- from notionary.blocks.models import Block, BlockChildrenResponse, BlockCreateRequest
3
+ from notionary.blocks.schemas import Block, BlockChildrenResponse, BlockCreatePayload
4
+ from notionary.http.client import NotionHttpClient
5
+ from notionary.utils.pagination import paginate_notion_api
5
6
 
6
7
 
7
- class NotionBlockClient(BaseNotionClient):
8
- """
9
- Client for Notion Block API operations.
10
- """
11
-
12
- async def get_block(self, block_id: str) -> Optional[Block]:
13
- """
14
- Retrieves a single block by its ID.
15
- """
16
- self.logger.debug("Retrieving block: %s", block_id)
8
+ class NotionBlockHttpClient(NotionHttpClient):
9
+ BATCH_SIZE = 100
17
10
 
11
+ async def get_block(self, block_id: str) -> Block:
18
12
  response = await self.get(f"blocks/{block_id}")
19
- if response:
20
- try:
21
- return Block.model_validate(response)
22
- except Exception as e:
23
- self.logger.error("Failed to parse block response: %s", str(e))
24
- return None
25
- return None
26
-
27
- async def get_blocks_by_page_id_recursively(
28
- self, page_id: str, parent_id: Optional[str] = None
29
- ) -> list[Block]:
30
- response = (
31
- await self.get_block_children(block_id=page_id)
32
- if parent_id is None
33
- else await self.get_block_children(block_id=parent_id)
34
- )
13
+ return Block.model_validate(response)
35
14
 
36
- if not response or not response.results:
37
- return []
15
+ async def delete_block(self, block_id: str) -> None:
16
+ self.logger.debug("Deleting block: %s", block_id)
17
+ await self.delete(f"blocks/{block_id}")
38
18
 
39
- blocks = response.results
19
+ async def get_block_tree(self, parent_block_id: str) -> list[Block]:
20
+ blocks_at_this_level = await self.get_all_block_children(parent_block_id)
40
21
 
41
- for block in blocks:
42
- if not block.has_children:
43
- continue
22
+ for block in blocks_at_this_level:
23
+ if block.has_children:
24
+ nested_children = await self.get_block_tree(parent_block_id=block.id)
25
+ block.children = nested_children
44
26
 
45
- block_id = block.id
46
- if not block_id:
47
- continue
27
+ return blocks_at_this_level
48
28
 
49
- children = await self.get_blocks_by_page_id_recursively(
50
- page_id=page_id, parent_id=block_id
51
- )
52
- if children:
53
- block.children = children
29
+ async def get_all_block_children(self, parent_block_id: str) -> list[Block]:
30
+ self.logger.debug("Retrieving all children for block: %s", parent_block_id)
54
31
 
55
- return blocks
32
+ all_blocks = await paginate_notion_api(self.get_block_children, block_id=parent_block_id)
33
+
34
+ self.logger.debug("Retrieved %d total children for block %s", len(all_blocks), parent_block_id)
35
+ return all_blocks
56
36
 
57
37
  async def get_block_children(
58
- self, block_id: str, start_cursor: Optional[str] = None, page_size: int = 100
59
- ) -> Optional[BlockChildrenResponse]:
60
- """
61
- Retrieves the children of a block with pagination support.
62
- """
38
+ self, block_id: str, start_cursor: str | None = None, page_size: int = 100
39
+ ) -> BlockChildrenResponse:
63
40
  self.logger.debug("Retrieving children of block: %s", block_id)
64
41
 
65
42
  params = {"page_size": min(page_size, 100)}
@@ -67,190 +44,85 @@ class NotionBlockClient(BaseNotionClient):
67
44
  params["start_cursor"] = start_cursor
68
45
 
69
46
  response = await self.get(f"blocks/{block_id}/children", params=params)
47
+ return BlockChildrenResponse.model_validate(response)
70
48
 
71
- if not response:
49
+ async def append_block_children(
50
+ self,
51
+ block_id: str,
52
+ children: list[BlockCreatePayload],
53
+ insert_after_block_id: str | None = None,
54
+ ) -> BlockChildrenResponse | None:
55
+ if not children:
56
+ self.logger.warning("No children provided to append")
72
57
  return None
73
58
 
74
- try:
75
- return BlockChildrenResponse.model_validate(response)
76
- except Exception as e:
77
- self.logger.error("Failed to parse block children response: %s", str(e))
78
- return None
59
+ self.logger.debug("Appending %d children to block: %s", len(children), block_id)
79
60
 
80
- async def get_all_block_children(self, block_id: str) -> list[Block]:
81
- """
82
- Retrieves ALL children of a block, handling pagination automatically.
83
- """
84
- all_blocks = []
85
- cursor = None
61
+ batches = self._split_into_batches(children)
86
62
 
87
- while True:
88
- response = await self.get_block_children(
89
- block_id=block_id, start_cursor=cursor, page_size=100
90
- )
63
+ if len(batches) == 1:
64
+ children_dicts = self._serialize_blocks(batches[0])
65
+ return await self._send_append_request(block_id, children_dicts, insert_after_block_id)
91
66
 
92
- if not response:
93
- break
67
+ return await self._send_batched_append_requests(block_id, batches, insert_after_block_id)
94
68
 
95
- all_blocks.extend(response.results)
69
+ def _split_into_batches(self, blocks: list[BlockCreatePayload]) -> list[list[BlockCreatePayload]]:
70
+ batches = []
71
+ for i in range(0, len(blocks), self.BATCH_SIZE):
72
+ batch = blocks[i : i + self.BATCH_SIZE]
73
+ batches.append(batch)
74
+ return batches
96
75
 
97
- if not response.has_more:
98
- break
76
+ def _serialize_blocks(self, blocks: list[BlockCreatePayload]) -> list[dict[str, Any]]:
77
+ return [block.model_dump(exclude_none=True) for block in blocks]
99
78
 
100
- cursor = response.next_cursor
79
+ async def _send_append_request(
80
+ self, block_id: str, children: list[dict[str, Any]], after_block_id: str | None = None
81
+ ) -> BlockChildrenResponse:
82
+ payload = {"children": children}
83
+ if after_block_id:
84
+ payload["after"] = after_block_id
101
85
 
102
- self.logger.debug(
103
- "Retrieved %d total children for block %s", len(all_blocks), block_id
104
- )
105
- return all_blocks
86
+ response = await self.patch(f"blocks/{block_id}/children", payload)
87
+ return BlockChildrenResponse.model_validate(response)
106
88
 
107
- async def append_block_children(
108
- self,
109
- block_id: str,
110
- children: list[BlockCreateRequest],
111
- after: Optional[str] = None,
112
- ) -> Optional[BlockChildrenResponse]:
113
- """
114
- Appends new child blocks to a parent block.
115
- Automatically handles batching for more than 100 blocks.
116
- """
117
- if not children:
118
- self.logger.warning("No children provided to append")
119
- return None
89
+ async def _send_batched_append_requests(
90
+ self, block_id: str, batches: list[list[BlockCreatePayload]], initial_after_block_id: str | None = None
91
+ ) -> BlockChildrenResponse:
92
+ total_blocks = sum(len(batch) for batch in batches)
93
+ self.logger.info("Appending %d blocks in %d batches", total_blocks, len(batches))
120
94
 
121
- self.logger.debug("Appending %d children to block: %s", len(children), block_id)
95
+ all_responses = []
96
+ after_block_id = initial_after_block_id
122
97
 
123
- # Convert Pydantic models to dictionaries for API
124
- children_dicts = [block.model_dump(exclude_none=True) for block in children]
125
-
126
- # If 100 or fewer blocks, use single request
127
- if len(children_dicts) <= 100:
128
- return await self._append_single_batch(block_id, children_dicts, after)
129
-
130
- # For more than 100 blocks, use batch processing
131
- return await self._append_multiple_batches(block_id, children_dicts, after)
132
-
133
- async def _append_single_batch(
134
- self, block_id: str, children: list[dict[str, Any]], after: Optional[str] = None
135
- ) -> Optional[BlockChildrenResponse]:
136
- """
137
- Appends a single batch of blocks (≤100).
138
- """
139
- data = {"children": children}
140
- if after:
141
- data["after"] = after
142
-
143
- response = await self.patch(f"blocks/{block_id}/children", data)
144
- if response:
145
- try:
146
- return BlockChildrenResponse.model_validate(response)
147
- except Exception as e:
148
- self.logger.error("Failed to parse append response: %s", str(e))
149
- return None
150
- return None
151
-
152
- async def _append_multiple_batches(
153
- self, block_id: str, children: list[dict[str, Any]], after: Optional[str] = None
154
- ) -> Optional[BlockChildrenResponse]:
155
- """
156
- Appends multiple batches of blocks, handling pagination.
157
- """
158
- all_results = []
159
- current_after = after
160
- batch_size = 100
161
-
162
- self.logger.info(
163
- "Processing %d blocks in batches of %d", len(children), batch_size
164
- )
98
+ for batch_index, batch in enumerate(batches, start=1):
99
+ self.logger.debug("Processing batch %d/%d (%d blocks)", batch_index, len(batches), len(batch))
165
100
 
166
- # Process blocks in chunks of 100
167
- for i in range(0, len(children), batch_size):
168
- batch = children[i : i + batch_size]
169
- batch_num = (i // batch_size) + 1
170
- total_batches = (len(children) + batch_size - 1) // batch_size
171
-
172
- self.logger.debug(
173
- "Processing batch %d/%d (%d blocks)",
174
- batch_num,
175
- total_batches,
176
- len(batch),
177
- )
178
-
179
- # Append current batch
180
- response = await self._append_single_batch(block_id, batch, current_after)
181
-
182
- if not response:
183
- self.logger.error(
184
- "Failed to append batch %d/%d", batch_num, total_batches
185
- )
186
- # Return partial results if we have any
187
- if all_results:
188
- return self._combine_batch_responses(all_results)
189
- return None
190
-
191
- all_results.append(response)
192
-
193
- # Update 'after' to the last block ID from this batch for next iteration
194
- if response.results:
195
- current_after = response.results[-1].id
101
+ children_dicts = self._serialize_blocks(batch)
102
+ response = await self._send_append_request(block_id, children_dicts, after_block_id)
103
+ all_responses.append(response)
196
104
 
197
- self.logger.debug(
198
- "Successfully appended batch %d/%d", batch_num, total_batches
199
- )
105
+ if response.results:
106
+ after_block_id = response.results[-1].id
200
107
 
201
- self.logger.info(
202
- "Successfully appended all %d blocks in %d batches",
203
- len(children),
204
- len(all_results),
205
- )
108
+ self.logger.debug("Completed batch %d/%d", batch_index, len(batches))
206
109
 
207
- # Combine all batch responses into a single response
208
- return self._combine_batch_responses(all_results)
110
+ self.logger.info("Successfully appended all blocks in %d batches", len(batches))
111
+ return self._merge_responses(all_responses)
209
112
 
210
- def _combine_batch_responses(
211
- self, responses: list[BlockChildrenResponse]
212
- ) -> BlockChildrenResponse:
213
- """
214
- Combines multiple batch responses into a single response.
215
- """
113
+ def _merge_responses(self, responses: list[BlockChildrenResponse]) -> BlockChildrenResponse:
216
114
  if not responses:
217
- # Return empty response structure
218
- return BlockChildrenResponse(
219
- object="list",
220
- results=[],
221
- next_cursor=None,
222
- has_more=False,
223
- type="block",
224
- block={},
225
- request_id="",
226
- )
227
-
228
- # Use the first response as template and combine all results
229
- combined = responses[0]
230
- all_blocks = []
231
-
232
- for response in responses:
233
- all_blocks.extend(response.results)
234
-
235
- # Create new combined response
236
- return BlockChildrenResponse(
237
- object=combined.object,
238
- results=all_blocks,
239
- next_cursor=None, # No pagination in combined result
240
- has_more=False, # All blocks are included
241
- type=combined.type,
242
- block=combined.block,
243
- request_id=responses[-1].request_id, # Use last request ID
244
- )
115
+ raise ValueError("Cannot merge empty response list - this should never happen")
245
116
 
246
- async def delete_block(self, block_id: str) -> Optional[Block]:
247
- """
248
- Deletes (archives) a block.
249
- """
250
- self.logger.debug("Deleting block: %s", block_id)
117
+ first_response = responses[0]
118
+ all_results = [block for response in responses for block in response.results]
251
119
 
252
- success = await self.delete(f"blocks/{block_id}")
253
- if success:
254
- # After deletion, retrieve the block to return the updated state
255
- return await self.get_block(block_id)
256
- return None
120
+ return BlockChildrenResponse(
121
+ object=first_response.object,
122
+ results=all_results,
123
+ next_cursor=None,
124
+ has_more=False,
125
+ type=first_response.type,
126
+ block=first_response.block,
127
+ request_id=responses[-1].request_id,
128
+ )
@@ -0,0 +1,167 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import StrEnum
4
+ from typing import Self
5
+
6
+
7
+ class BlockColor(StrEnum):
8
+ BLUE = "blue"
9
+ BLUE_BACKGROUND = "blue_background"
10
+ BROWN = "brown"
11
+ BROWN_BACKGROUND = "brown_background"
12
+ DEFAULT = "default"
13
+ GRAY = "gray"
14
+ GRAY_BACKGROUND = "gray_background"
15
+ GREEN = "green"
16
+ GREEN_BACKGROUND = "green_background"
17
+ ORANGE = "orange"
18
+ ORANGE_BACKGROUND = "orange_background"
19
+ YELLOW = "yellow"
20
+ YELLOW_BACKGROUND = "yellow_background"
21
+ PINK = "pink"
22
+ PINK_BACKGROUND = "pink_background"
23
+ PURPLE = "purple"
24
+ PURPLE_BACKGROUND = "purple_background"
25
+ RED = "red"
26
+ RED_BACKGROUND = "red_background"
27
+ DEFAULT_BACKGROUND = "default_background"
28
+
29
+
30
+ class BlockType(StrEnum):
31
+ AUDIO = "audio"
32
+ BOOKMARK = "bookmark"
33
+ BREADCRUMB = "breadcrumb"
34
+ BULLETED_LIST_ITEM = "bulleted_list_item"
35
+ CALLOUT = "callout"
36
+ CHILD_DATABASE = "child_database"
37
+ CHILD_PAGE = "child_page"
38
+ CODE = "code"
39
+ COLUMN = "column"
40
+ COLUMN_LIST = "column_list"
41
+ DIVIDER = "divider"
42
+ EMBED = "embed"
43
+ EQUATION = "equation"
44
+ FILE = "file"
45
+ HEADING_1 = "heading_1"
46
+ HEADING_2 = "heading_2"
47
+ HEADING_3 = "heading_3"
48
+ IMAGE = "image"
49
+ LINK_PREVIEW = "link_preview"
50
+ LINK_TO_PAGE = "link_to_page"
51
+ NUMBERED_LIST_ITEM = "numbered_list_item"
52
+ PARAGRAPH = "paragraph"
53
+ PDF = "pdf"
54
+ QUOTE = "quote"
55
+ SYNCED_BLOCK = "synced_block"
56
+ TABLE = "table"
57
+ TABLE_OF_CONTENTS = "table_of_contents"
58
+ TABLE_ROW = "table_row"
59
+ TO_DO = "to_do"
60
+ TOGGLE = "toggle"
61
+ UNSUPPORTED = "unsupported"
62
+ VIDEO = "video"
63
+
64
+
65
+ class FileType(StrEnum):
66
+ EXTERNAL = "external"
67
+ FILE = "file"
68
+ FILE_UPLOAD = "file_upload"
69
+
70
+
71
+ class CodeLanguage(StrEnum):
72
+ ABAP = "abap"
73
+ ARDUINO = "arduino"
74
+ BASH = "bash"
75
+ BASIC = "basic"
76
+ C = "c"
77
+ CLOJURE = "clojure"
78
+ COFFEESCRIPT = "coffeescript"
79
+ CPP = "c++"
80
+ CSHARP = "c#"
81
+ CSS = "css"
82
+ DART = "dart"
83
+ DIFF = "diff"
84
+ DOCKER = "docker"
85
+ ELIXIR = "elixir"
86
+ ELM = "elm"
87
+ ERLANG = "erlang"
88
+ FLOW = "flow"
89
+ FORTRAN = "fortran"
90
+ FSHARP = "f#"
91
+ GHERKIN = "gherkin"
92
+ GLSL = "glsl"
93
+ GO = "go"
94
+ GRAPHQL = "graphql"
95
+ GROOVY = "groovy"
96
+ HASKELL = "haskell"
97
+ HTML = "html"
98
+ JAVA = "java"
99
+ JAVASCRIPT = "javascript"
100
+ JSON = "json"
101
+ JULIA = "julia"
102
+ KOTLIN = "kotlin"
103
+ LATEX = "latex"
104
+ LESS = "less"
105
+ LISP = "lisp"
106
+ LIVESCRIPT = "livescript"
107
+ LUA = "lua"
108
+ MAKEFILE = "makefile"
109
+ MARKDOWN = "markdown"
110
+ MARKUP = "markup"
111
+ MATLAB = "matlab"
112
+ MERMAID = "mermaid"
113
+ NIX = "nix"
114
+ OBJECTIVE_C = "objective-c"
115
+ OCAML = "ocaml"
116
+ PASCAL = "pascal"
117
+ PERL = "perl"
118
+ PHP = "php"
119
+ PLAIN_TEXT = "plain text"
120
+ POWERSHELL = "powershell"
121
+ PROLOG = "prolog"
122
+ PROTOBUF = "protobuf"
123
+ PYTHON = "python"
124
+ R = "r"
125
+ REASON = "reason"
126
+ RUBY = "ruby"
127
+ RUST = "rust"
128
+ SASS = "sass"
129
+ SCALA = "scala"
130
+ SCHEME = "scheme"
131
+ SCSS = "scss"
132
+ SHELL = "shell"
133
+ SQL = "sql"
134
+ SWIFT = "swift"
135
+ TYPESCRIPT = "typescript"
136
+ VB_NET = "vb.net"
137
+ VERILOG = "verilog"
138
+ VHDL = "vhdl"
139
+ VISUAL_BASIC = "visual basic"
140
+ WEBASSEMBLY = "webassembly"
141
+ XML = "xml"
142
+ YAML = "yaml"
143
+ JAVA_C_CPP_CSHARP = "java/c/c++/c#"
144
+
145
+ @classmethod
146
+ def from_string(cls, lang_str: str | None, default: Self | None = None) -> Self:
147
+ if not lang_str:
148
+ return default if default is not None else cls.PLAIN_TEXT
149
+
150
+ normalized = lang_str.lower().strip()
151
+
152
+ aliases = {
153
+ "cpp": cls.CPP,
154
+ "c++": cls.CPP,
155
+ "js": cls.JAVASCRIPT,
156
+ "py": cls.PYTHON,
157
+ "ts": cls.TYPESCRIPT,
158
+ }
159
+
160
+ if normalized in aliases:
161
+ return aliases[normalized]
162
+
163
+ for member in cls:
164
+ if member.value.lower() == normalized:
165
+ return member
166
+
167
+ return default if default is not None else cls.PLAIN_TEXT