notionary 0.2.23__tar.gz → 0.2.24__tar.gz

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 (231) hide show
  1. {notionary-0.2.23 → notionary-0.2.24}/PKG-INFO +16 -1
  2. {notionary-0.2.23 → notionary-0.2.24}/README.md +14 -0
  3. {notionary-0.2.23 → notionary-0.2.24}/notionary/__init__.py +1 -1
  4. notionary-0.2.24/notionary/blocks/__init__.py +5 -0
  5. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/audio/__init__.py +0 -2
  6. notionary-0.2.24/notionary/blocks/audio/audio_element.py +158 -0
  7. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/audio/audio_markdown_node.py +4 -17
  8. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bookmark/__init__.py +0 -2
  9. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bookmark/bookmark_markdown_node.py +5 -21
  10. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/breadcrumbs/__init__.py +0 -2
  11. notionary-0.2.24/notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +13 -0
  12. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bulleted_list/__init__.py +0 -2
  13. notionary-0.2.24/notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +20 -0
  14. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bulleted_list/bulleted_list_models.py +0 -1
  15. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/callout/__init__.py +0 -2
  16. notionary-0.2.24/notionary/blocks/callout/callout_markdown_node.py +19 -0
  17. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/callout/callout_models.py +3 -4
  18. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/code/code_markdown_node.py +5 -19
  19. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/__init__.py +0 -4
  20. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_list_markdown_node.py +3 -19
  21. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_markdown_node.py +4 -21
  22. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/divider/__init__.py +0 -2
  23. notionary-0.2.24/notionary/blocks/divider/divider_markdown_node.py +11 -0
  24. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/embed/__init__.py +0 -2
  25. notionary-0.2.24/notionary/blocks/embed/embed_markdown_node.py +19 -0
  26. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/equation/__init__.py +0 -1
  27. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/equation/equation_element_markdown_node.py +3 -15
  28. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/file/__init__.py +0 -2
  29. notionary-0.2.24/notionary/blocks/file/file_element.py +133 -0
  30. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/file/file_element_markdown_node.py +4 -17
  31. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/heading/__init__.py +0 -2
  32. notionary-0.2.24/notionary/blocks/heading/heading_markdown_node.py +16 -0
  33. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/heading/heading_models.py +3 -3
  34. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/image_block/__init__.py +0 -2
  35. notionary-0.2.24/notionary/blocks/image_block/image_element.py +130 -0
  36. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/image_block/image_markdown_node.py +5 -20
  37. {notionary-0.2.23/notionary → notionary-0.2.24/notionary/blocks}/markdown/markdown_builder.py +29 -233
  38. notionary-0.2.24/notionary/blocks/markdown/markdown_node.py +25 -0
  39. notionary-0.2.24/notionary/blocks/mixins/file_upload/__init__.py +3 -0
  40. notionary-0.2.24/notionary/blocks/mixins/file_upload/file_upload_mixin.py +320 -0
  41. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/numbered_list/__init__.py +0 -1
  42. notionary-0.2.24/notionary/blocks/numbered_list/numbered_list_markdown_node.py +17 -0
  43. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/numbered_list/numbered_list_models.py +3 -3
  44. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/paragraph/__init__.py +0 -2
  45. notionary-0.2.24/notionary/blocks/paragraph/paragraph_markdown_node.py +16 -0
  46. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/pdf/__init__.py +0 -2
  47. notionary-0.2.24/notionary/blocks/pdf/pdf_element.py +146 -0
  48. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/pdf/pdf_markdown_node.py +5 -18
  49. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/quote/__init__.py +0 -2
  50. notionary-0.2.24/notionary/blocks/quote/quote_markdown_node.py +16 -0
  51. notionary-0.2.24/notionary/blocks/registry/__init__.py +3 -0
  52. notionary-0.2.24/notionary/blocks/registry/block_registry.py +150 -0
  53. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table/__init__.py +0 -2
  54. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table/table_markdown_node.py +17 -16
  55. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table_of_contents/__init__.py +0 -2
  56. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table_of_contents/table_of_contents_element.py +27 -15
  57. notionary-0.2.24/notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +21 -0
  58. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table_of_contents/table_of_contents_models.py +2 -2
  59. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/todo/__init__.py +0 -2
  60. notionary-0.2.24/notionary/blocks/todo/todo_markdown_node.py +21 -0
  61. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/todo/todo_models.py +2 -3
  62. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggle/__init__.py +0 -2
  63. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggle/toggle_markdown_node.py +5 -19
  64. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggleable_heading/__init__.py +0 -2
  65. notionary-0.2.24/notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +34 -0
  66. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/video/__init__.py +0 -2
  67. notionary-0.2.24/notionary/blocks/video/video_element.py +187 -0
  68. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/video/video_markdown_node.py +4 -15
  69. {notionary-0.2.23 → notionary-0.2.24}/notionary/comments/client.py +1 -1
  70. {notionary-0.2.23 → notionary-0.2.24}/notionary/file_upload/client.py +3 -2
  71. {notionary-0.2.23 → notionary-0.2.24}/notionary/file_upload/models.py +10 -1
  72. {notionary-0.2.23 → notionary-0.2.24}/notionary/file_upload/notion_file_upload.py +5 -5
  73. notionary-0.2.24/notionary/page/markdown_whitespace_processor.py +129 -0
  74. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/notion_page.py +35 -40
  75. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/page_content_deleting_service.py +1 -1
  76. notionary-0.2.24/notionary/page/page_content_writer.py +80 -0
  77. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/page_context.py +0 -5
  78. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/column_list_renderer.py +2 -2
  79. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/column_renderer.py +2 -2
  80. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/line_renderer.py +2 -2
  81. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/toggle_renderer.py +2 -2
  82. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/toggleable_heading_renderer.py +2 -2
  83. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/toggle_handler.py +8 -4
  84. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/toggleable_heading_handler.py +3 -2
  85. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/markdown_to_notion_converter.py +74 -30
  86. notionary-0.2.24/notionary/schemas/__init__.py +3 -0
  87. notionary-0.2.24/notionary/schemas/base.py +73 -0
  88. {notionary-0.2.23 → notionary-0.2.24}/notionary/shared/__init__.py +1 -3
  89. {notionary-0.2.23 → notionary-0.2.24}/pyproject.toml +3 -1
  90. notionary-0.2.23/notionary/blocks/__init__.py +0 -3
  91. notionary-0.2.23/notionary/blocks/audio/audio_element.py +0 -115
  92. notionary-0.2.23/notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -32
  93. notionary-0.2.23/notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -34
  94. notionary-0.2.23/notionary/blocks/callout/callout_markdown_node.py +0 -33
  95. notionary-0.2.23/notionary/blocks/divider/divider_markdown_node.py +0 -25
  96. notionary-0.2.23/notionary/blocks/embed/embed_markdown_node.py +0 -32
  97. notionary-0.2.23/notionary/blocks/file/file_element.py +0 -112
  98. notionary-0.2.23/notionary/blocks/guards.py +0 -22
  99. notionary-0.2.23/notionary/blocks/heading/heading_markdown_node.py +0 -30
  100. notionary-0.2.23/notionary/blocks/image_block/image_element.py +0 -89
  101. notionary-0.2.23/notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -31
  102. notionary-0.2.23/notionary/blocks/paragraph/paragraph_markdown_node.py +0 -26
  103. notionary-0.2.23/notionary/blocks/pdf/pdf_element.py +0 -97
  104. notionary-0.2.23/notionary/blocks/quote/quote_markdown_node.py +0 -26
  105. notionary-0.2.23/notionary/blocks/registry/__init__.py +0 -4
  106. notionary-0.2.23/notionary/blocks/registry/block_registry.py +0 -95
  107. notionary-0.2.23/notionary/blocks/registry/block_registry_builder.py +0 -264
  108. notionary-0.2.23/notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -35
  109. notionary-0.2.23/notionary/blocks/todo/todo_markdown_node.py +0 -32
  110. notionary-0.2.23/notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -51
  111. notionary-0.2.23/notionary/blocks/video/video_element.py +0 -111
  112. notionary-0.2.23/notionary/markdown/makdown_document_model.py +0 -0
  113. notionary-0.2.23/notionary/markdown/markdown_document_model.py +0 -228
  114. notionary-0.2.23/notionary/markdown/markdown_node.py +0 -30
  115. notionary-0.2.23/notionary/models/notion_database_response.py +0 -0
  116. notionary-0.2.23/notionary/page/page_content_writer.py +0 -177
  117. notionary-0.2.23/notionary/page/writer/markdown_to_notion_formatting_post_processor.py +0 -73
  118. notionary-0.2.23/notionary/page/writer/markdown_to_notion_post_processor.py +0 -0
  119. {notionary-0.2.23 → notionary-0.2.24}/LICENSE +0 -0
  120. {notionary-0.2.23 → notionary-0.2.24}/notionary/base_notion_client.py +0 -0
  121. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/_bootstrap.py +0 -0
  122. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/audio/audio_models.py +0 -0
  123. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/base_block_element.py +0 -0
  124. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bookmark/bookmark_element.py +0 -0
  125. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bookmark/bookmark_models.py +0 -0
  126. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -0
  127. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -0
  128. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bulleted_list/bulleted_list_element.py +0 -0
  129. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/callout/callout_element.py +0 -0
  130. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_database/__init__.py +0 -0
  131. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_database/child_database_element.py +0 -0
  132. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_database/child_database_models.py +0 -0
  133. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_page/__init__.py +0 -0
  134. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_page/child_page_element.py +0 -0
  135. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_page/child_page_models.py +0 -0
  136. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/client.py +0 -0
  137. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/code/__init__.py +0 -0
  138. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/code/code_element.py +0 -0
  139. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/code/code_models.py +0 -0
  140. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_element.py +0 -0
  141. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_list_element.py +0 -0
  142. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_models.py +0 -0
  143. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/divider/divider_element.py +0 -0
  144. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/divider/divider_models.py +0 -0
  145. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/embed/embed_element.py +0 -0
  146. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/embed/embed_models.py +0 -0
  147. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/equation/equation_element.py +0 -0
  148. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/equation/equation_models.py +0 -0
  149. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/file/file_element_models.py +0 -0
  150. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/heading/heading_element.py +0 -0
  151. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/image_block/image_models.py +0 -0
  152. /notionary-0.2.23/notionary/database/factory.py → /notionary-0.2.24/notionary/blocks/markdown/markdown_document_model.py +0 -0
  153. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/mixins/captions/__init__.py +0 -0
  154. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -0
  155. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/mixins/captions/caption_mixin.py +0 -0
  156. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/models.py +0 -0
  157. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/numbered_list/numbered_list_element.py +0 -0
  158. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/paragraph/paragraph_element.py +0 -0
  159. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/paragraph/paragraph_models.py +0 -0
  160. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/pdf/pdf_models.py +0 -0
  161. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/quote/quote_element.py +0 -0
  162. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/quote/quote_models.py +0 -0
  163. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/rich_text/__init__.py +0 -0
  164. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/rich_text/rich_text_models.py +0 -0
  165. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/rich_text/text_inline_formatter.py +0 -0
  166. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/syntax_prompt_builder.py +0 -0
  167. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table/table_element.py +0 -0
  168. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table/table_models.py +0 -0
  169. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/todo/todo_element.py +0 -0
  170. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggle/toggle_element.py +0 -0
  171. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggle/toggle_models.py +0 -0
  172. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -0
  173. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/types.py +0 -0
  174. {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/video/video_element_models.py +0 -0
  175. {notionary-0.2.23 → notionary-0.2.24}/notionary/comments/__init__.py +0 -0
  176. {notionary-0.2.23 → notionary-0.2.24}/notionary/comments/models.py +0 -0
  177. {notionary-0.2.23 → notionary-0.2.24}/notionary/database/__init__.py +0 -0
  178. {notionary-0.2.23 → notionary-0.2.24}/notionary/database/client.py +0 -0
  179. {notionary-0.2.23 → notionary-0.2.24}/notionary/database/database.py +0 -0
  180. {notionary-0.2.23 → notionary-0.2.24}/notionary/database/database_filter_builder.py +0 -0
  181. {notionary-0.2.23 → notionary-0.2.24}/notionary/database/database_provider.py +0 -0
  182. {notionary-0.2.23 → notionary-0.2.24}/notionary/database/exceptions.py +0 -0
  183. /notionary-0.2.23/notionary/markdown/___init__.py → /notionary-0.2.24/notionary/database/factory.py +0 -0
  184. {notionary-0.2.23 → notionary-0.2.24}/notionary/database/models.py +0 -0
  185. {notionary-0.2.23 → notionary-0.2.24}/notionary/database/notion_database.py +0 -0
  186. {notionary-0.2.23 → notionary-0.2.24}/notionary/file_upload/__init__.py +0 -0
  187. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/client.py +0 -0
  188. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/models.py +0 -0
  189. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/property_formatter.py +0 -0
  190. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/__init__.py +0 -0
  191. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/base_block_renderer.py +0 -0
  192. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/block_processing_context.py +0 -0
  193. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/block_rendering_context.py +0 -0
  194. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/equation_renderer.py +0 -0
  195. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/numbered_list_renderer.py +0 -0
  196. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/page_content_retriever.py +0 -0
  197. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/search_filter_builder.py +0 -0
  198. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/utils.py +0 -0
  199. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/__init__.py +0 -0
  200. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/code_handler.py +0 -0
  201. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/column_handler.py +0 -0
  202. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/column_list_handler.py +0 -0
  203. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/equation_handler.py +0 -0
  204. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/line_handler.py +0 -0
  205. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/line_processing_context.py +0 -0
  206. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/regular_line_handler.py +0 -0
  207. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/table_handler.py +0 -0
  208. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/markdown_to_notion_converter_context.py +0 -0
  209. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
  210. {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/notion_text_length_processor.py +0 -0
  211. {notionary-0.2.23 → notionary-0.2.24}/notionary/shared/name_to_id_resolver.py +0 -0
  212. {notionary-0.2.23 → notionary-0.2.24}/notionary/telemetry/__init__.py +0 -0
  213. {notionary-0.2.23 → notionary-0.2.24}/notionary/telemetry/service.py +0 -0
  214. {notionary-0.2.23 → notionary-0.2.24}/notionary/telemetry/views.py +0 -0
  215. {notionary-0.2.23 → notionary-0.2.24}/notionary/user/__init__.py +0 -0
  216. {notionary-0.2.23 → notionary-0.2.24}/notionary/user/base_notion_user.py +0 -0
  217. {notionary-0.2.23 → notionary-0.2.24}/notionary/user/client.py +0 -0
  218. {notionary-0.2.23 → notionary-0.2.24}/notionary/user/models.py +0 -0
  219. {notionary-0.2.23 → notionary-0.2.24}/notionary/user/notion_bot_user.py +0 -0
  220. {notionary-0.2.23 → notionary-0.2.24}/notionary/user/notion_user.py +0 -0
  221. {notionary-0.2.23 → notionary-0.2.24}/notionary/user/notion_user_manager.py +0 -0
  222. {notionary-0.2.23 → notionary-0.2.24}/notionary/util/__init__.py +0 -0
  223. {notionary-0.2.23 → notionary-0.2.24}/notionary/util/concurrency_limiter.py +0 -0
  224. {notionary-0.2.23 → notionary-0.2.24}/notionary/util/factory_decorator.py +0 -0
  225. {notionary-0.2.23 → notionary-0.2.24}/notionary/util/factory_only.py +0 -0
  226. {notionary-0.2.23 → notionary-0.2.24}/notionary/util/fuzzy.py +0 -0
  227. {notionary-0.2.23 → notionary-0.2.24}/notionary/util/logging_mixin.py +0 -0
  228. {notionary-0.2.23 → notionary-0.2.24}/notionary/util/page_id_utils.py +0 -0
  229. {notionary-0.2.23 → notionary-0.2.24}/notionary/util/singleton.py +0 -0
  230. {notionary-0.2.23 → notionary-0.2.24}/notionary/util/singleton_metaclass.py +0 -0
  231. {notionary-0.2.23 → notionary-0.2.24}/notionary/workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: notionary
3
- Version: 0.2.23
3
+ Version: 0.2.24
4
4
  Summary: Python library for programmatic Notion workspace management - databases, pages, and content with advanced Markdown support
5
5
  License: MIT
6
6
  Author: Mathis Arends
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Dist: aiofiles (>=24.1.0,<25.0.0)
16
17
  Requires-Dist: httpx (>=0.28.0)
17
18
  Requires-Dist: posthog (>=6.3.1,<7.0.0)
18
19
  Requires-Dist: pydantic (>=2.11.4)
@@ -64,6 +65,13 @@ NOTION_SECRET=your_integration_key
64
65
 
65
66
  ### Simple Flow: Find → Create → Update
66
67
 
68
+ <video width="100%" controls>
69
+ <source src="./static/demo.mp4" type="video/mp4">
70
+ Your browser does not support the video tag.
71
+ </video>
72
+
73
+ _Demo: Converting markdown to structured Notion content with callouts, columns, and tables_
74
+
67
75
  ```python
68
76
  import asyncio
69
77
  from notionary import NotionPage, NotionDatabase
@@ -111,6 +119,13 @@ asyncio.run(main())
111
119
 
112
120
  ### Create Rich Database Entries
113
121
 
122
+ <video width="100%" controls>
123
+ <source src="./static/create_page_in_database_demo.mp4" type="video/mp4">
124
+ Your browser does not support the video tag.
125
+ </video>
126
+
127
+ _Demo: Creating a styled project page in a Notion database with properties, content, and rich formatting_
128
+
114
129
  ```python
115
130
  # Work with databases - connect and create styled entries
116
131
  db = await NotionDatabase.from_database_name("Projects")
@@ -42,6 +42,13 @@ NOTION_SECRET=your_integration_key
42
42
 
43
43
  ### Simple Flow: Find → Create → Update
44
44
 
45
+ <video width="100%" controls>
46
+ <source src="./static/demo.mp4" type="video/mp4">
47
+ Your browser does not support the video tag.
48
+ </video>
49
+
50
+ _Demo: Converting markdown to structured Notion content with callouts, columns, and tables_
51
+
45
52
  ```python
46
53
  import asyncio
47
54
  from notionary import NotionPage, NotionDatabase
@@ -89,6 +96,13 @@ asyncio.run(main())
89
96
 
90
97
  ### Create Rich Database Entries
91
98
 
99
+ <video width="100%" controls>
100
+ <source src="./static/create_page_in_database_demo.mp4" type="video/mp4">
101
+ Your browser does not support the video tag.
102
+ </video>
103
+
104
+ _Demo: Creating a styled project page in a Notion database with properties, content, and rich formatting_
105
+
92
106
  ```python
93
107
  # Work with databases - connect and create styled entries
94
108
  db = await NotionDatabase.from_database_name("Projects")
@@ -4,7 +4,7 @@ bootstrap_blocks()
4
4
 
5
5
  from .database import DatabaseFilterBuilder, NotionDatabase
6
6
  from .file_upload import NotionFileUpload
7
- from .markdown.markdown_builder import MarkdownBuilder
7
+ from .blocks.markdown.markdown_builder import MarkdownBuilder
8
8
  from .page.notion_page import NotionPage
9
9
  from .user import NotionBotUser, NotionUser, NotionUserManager
10
10
  from .workspace import NotionWorkspace
@@ -0,0 +1,5 @@
1
+ from ._bootstrap import bootstrap_blocks
2
+
3
+ __all__ = [
4
+ "bootstrap_blocks",
5
+ ]
@@ -1,6 +1,5 @@
1
1
  from notionary.blocks.audio.audio_element import AudioElement
2
2
  from notionary.blocks.audio.audio_markdown_node import (
3
- AudioMarkdownBlockParams,
4
3
  AudioMarkdownNode,
5
4
  )
6
5
  from notionary.blocks.audio.audio_models import CreateAudioBlock
@@ -9,5 +8,4 @@ __all__ = [
9
8
  "AudioElement",
10
9
  "CreateAudioBlock",
11
10
  "AudioMarkdownNode",
12
- "AudioMarkdownBlockParams",
13
11
  ]
@@ -0,0 +1,158 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from pathlib import Path
5
+ from typing import Optional
6
+
7
+ from notionary.blocks.audio.audio_models import CreateAudioBlock
8
+ from notionary.blocks.base_block_element import BaseBlockElement
9
+ from notionary.blocks.file.file_element_models import (
10
+ ExternalFile,
11
+ FileBlock,
12
+ FileType,
13
+ FileUploadFile,
14
+ )
15
+ from notionary.blocks.mixins.captions import CaptionMixin
16
+ from notionary.blocks.mixins.file_upload.file_upload_mixin import FileUploadMixin
17
+ from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
18
+ from notionary.blocks.models import Block, BlockCreateResult, BlockType
19
+ from notionary.util.logging_mixin import LoggingMixin
20
+
21
+
22
+ class AudioElement(BaseBlockElement, FileUploadMixin, LoggingMixin, CaptionMixin):
23
+ r"""
24
+ Handles conversion between Markdown audio embeds and Notion audio blocks.
25
+
26
+ Supports both external URLs and local audio file uploads.
27
+
28
+ Markdown audio syntax:
29
+ - [audio](https://example.com/audio.mp3) - External URL
30
+ - [audio](./local/song.mp3) - Local audio file (will be uploaded)
31
+ - [audio](C:\Music\podcast.wav) - Absolute local path (will be uploaded)
32
+ - [audio](https://example.com/audio.mp3)(caption:Episode 1) - URL with caption
33
+ """
34
+
35
+ AUDIO_PATTERN = re.compile(r"\[audio\]\(([^)]+)\)")
36
+ SUPPORTED_EXTENSIONS = {".mp3", ".wav", ".ogg", ".oga", ".m4a"}
37
+
38
+ @classmethod
39
+ def match_notion(cls, block: Block) -> bool:
40
+ """Check if this element can handle the given Notion block."""
41
+ return block.type == BlockType.AUDIO
42
+
43
+ @classmethod
44
+ async def markdown_to_notion(cls, text: str) -> Optional[BlockCreateResult]:
45
+ """Convert markdown audio embed to Notion audio block."""
46
+ # Extract the path/URL
47
+ path = cls._extract_audio_path(text.strip())
48
+ if not path:
49
+ return None
50
+
51
+ # Check if it's a local file path
52
+ if cls._is_local_file_path(path):
53
+ # Verify file exists and has supported extension
54
+ audio_path = Path(path)
55
+ if not audio_path.exists():
56
+ cls.logger.warning(f"Audio file not found: {path}")
57
+ return None
58
+
59
+ if audio_path.suffix.lower() not in cls.SUPPORTED_EXTENSIONS:
60
+ cls.logger.warning(f"Unsupported audio format: {audio_path.suffix}")
61
+ return None
62
+
63
+ cls.logger.info(f"Uploading local audio file: {path}")
64
+
65
+ # Upload the local audio file
66
+ file_upload_id = await cls._upload_local_file(path, "audio")
67
+ if not file_upload_id:
68
+ cls.logger.error(f"Failed to upload audio file: {path}")
69
+ return None
70
+
71
+ cls.logger.info(
72
+ f"Successfully uploaded audio file with ID: {file_upload_id}"
73
+ )
74
+
75
+ # Use mixin to extract caption (if present anywhere in text)
76
+ caption_text = cls.extract_caption(text.strip())
77
+ caption_rich_text = cls.build_caption_rich_text(caption_text or "")
78
+
79
+ audio_content = FileBlock(
80
+ type=FileType.FILE_UPLOAD,
81
+ file_upload=FileUploadFile(id=file_upload_id),
82
+ caption=caption_rich_text,
83
+ )
84
+
85
+ return CreateAudioBlock(audio=audio_content)
86
+
87
+ else:
88
+ # Handle external URL - accept any URL (validation happens at API level)
89
+ # Use mixin to extract caption (if present anywhere in text)
90
+ caption_text = cls.extract_caption(text.strip())
91
+ caption_rich_text = cls.build_caption_rich_text(caption_text or "")
92
+
93
+ audio_content = FileBlock(
94
+ type=FileType.EXTERNAL,
95
+ external=ExternalFile(url=path),
96
+ caption=caption_rich_text,
97
+ )
98
+
99
+ return CreateAudioBlock(audio=audio_content)
100
+
101
+ @classmethod
102
+ async def notion_to_markdown(cls, block: Block) -> Optional[str]:
103
+ """Convert Notion audio block to markdown audio embed."""
104
+ if block.type != BlockType.AUDIO or block.audio is None:
105
+ return None
106
+
107
+ audio = block.audio
108
+ url = None
109
+
110
+ # Handle both external URLs and uploaded files
111
+ if audio.type == FileType.EXTERNAL and audio.external is not None:
112
+ url = audio.external.url
113
+ elif audio.type == FileType.FILE_UPLOAD and audio.file_upload is not None:
114
+ url = audio.file_upload.url
115
+
116
+ if not url:
117
+ return None
118
+
119
+ result = f"[audio]({url})"
120
+
121
+ # Add caption if present
122
+ caption_markdown = await cls.format_caption_for_markdown(audio.caption or [])
123
+ if caption_markdown:
124
+ result += caption_markdown
125
+
126
+ return result
127
+
128
+ @classmethod
129
+ def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
130
+ """Get system prompt information for audio blocks."""
131
+ return BlockElementMarkdownInformation(
132
+ block_type=cls.__name__,
133
+ description="Audio blocks embed audio files from external URLs or local files with optional captions",
134
+ syntax_examples=[
135
+ "[audio](https://example.com/song.mp3)",
136
+ "[audio](./local/podcast.wav)",
137
+ "[audio](C:\\Music\\interview.mp3)",
138
+ "[audio](https://example.com/podcast.wav)(caption:Episode 1)",
139
+ "(caption:Background music)[audio](./song.mp3)",
140
+ "[audio](./interview.mp3)(caption:**Live** interview)",
141
+ ],
142
+ usage_guidelines="Use for embedding audio files like music, podcasts, or sound effects. Supports both external URLs and local file uploads. Supports common audio formats (mp3, wav, ogg, m4a). Caption supports rich text formatting and is optional.",
143
+ )
144
+
145
+ @classmethod
146
+ def _is_likely_audio_url(cls, url: str) -> bool:
147
+ return any(url.lower().endswith(ext) for ext in cls.SUPPORTED_EXTENSIONS)
148
+
149
+ @classmethod
150
+ def _extract_audio_path(cls, text: str) -> Optional[str]:
151
+ """Extract audio path/URL from text, handling caption patterns."""
152
+ clean_text = cls.remove_caption(text)
153
+
154
+ match = cls.AUDIO_PATTERN.search(clean_text)
155
+ if match:
156
+ return match.group(1).strip()
157
+
158
+ return None
@@ -1,30 +1,17 @@
1
- from __future__ import annotations
2
-
3
1
  from typing import Optional
4
2
 
5
- from pydantic import BaseModel
6
-
7
- from notionary.markdown.markdown_node import MarkdownNode
3
+ from notionary.blocks.markdown.markdown_node import MarkdownNode
8
4
  from notionary.blocks.mixins.captions import CaptionMarkdownNodeMixin
9
5
 
10
6
 
11
- class AudioMarkdownBlockParams(BaseModel):
12
- url: str
13
- caption: Optional[str] = None
14
-
15
-
16
7
  class AudioMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
17
8
  """
9
+ Enhanced Audio node with Pydantic integration.
18
10
  Programmatic interface for creating Notion-style audio blocks.
19
11
  """
20
12
 
21
- def __init__(self, url: str, caption: Optional[str] = None):
22
- self.url = url
23
- self.caption = caption
24
-
25
- @classmethod
26
- def from_params(cls, params: AudioMarkdownBlockParams) -> AudioMarkdownNode:
27
- return cls(url=params.url, caption=params.caption)
13
+ url: str
14
+ caption: Optional[str] = None
28
15
 
29
16
  def to_markdown(self) -> str:
30
17
  """Return the Markdown representation.
@@ -1,6 +1,5 @@
1
1
  from notionary.blocks.bookmark.bookmark_element import BookmarkElement
2
2
  from notionary.blocks.bookmark.bookmark_markdown_node import (
3
- BookmarkMarkdownBlockParams,
4
3
  BookmarkMarkdownNode,
5
4
  )
6
5
  from notionary.blocks.bookmark.bookmark_models import BookmarkBlock, CreateBookmarkBlock
@@ -10,5 +9,4 @@ __all__ = [
10
9
  "BookmarkBlock",
11
10
  "CreateBookmarkBlock",
12
11
  "BookmarkMarkdownNode",
13
- "BookmarkMarkdownBlockParams",
14
12
  ]
@@ -1,34 +1,18 @@
1
- from __future__ import annotations
2
-
3
1
  from typing import Optional
4
2
 
5
- from pydantic import BaseModel
6
-
7
- from notionary.markdown.markdown_node import MarkdownNode
3
+ from notionary.blocks.markdown.markdown_node import MarkdownNode
8
4
  from notionary.blocks.mixins.captions import CaptionMarkdownNodeMixin
9
5
 
10
6
 
11
- class BookmarkMarkdownBlockParams(BaseModel):
12
- url: str
13
- title: Optional[str] = None
14
- caption: Optional[str] = None
15
-
16
-
17
7
  class BookmarkMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
18
8
  """
9
+ Enhanced Bookmark node with Pydantic integration.
19
10
  Programmatic interface for creating Notion-style bookmark Markdown blocks.
20
11
  """
21
12
 
22
- def __init__(
23
- self, url: str, title: Optional[str] = None, caption: Optional[str] = None
24
- ):
25
- self.url = url
26
- self.title = title
27
- self.caption = caption
28
-
29
- @classmethod
30
- def from_params(cls, params: BookmarkMarkdownBlockParams) -> BookmarkMarkdownNode:
31
- return cls(url=params.url, title=params.title, caption=params.caption)
13
+ url: str
14
+ title: Optional[str] = None
15
+ caption: Optional[str] = None
32
16
 
33
17
  def to_markdown(self) -> str:
34
18
  """Return the Markdown representation.
@@ -1,6 +1,5 @@
1
1
  from notionary.blocks.breadcrumbs.breadcrumb_element import BreadcrumbElement
2
2
  from notionary.blocks.breadcrumbs.breadcrumb_markdown_node import (
3
- BreadcrumbMarkdownBlockParams,
4
3
  BreadcrumbMarkdownNode,
5
4
  )
6
5
  from notionary.blocks.breadcrumbs.breadcrumb_models import (
@@ -13,5 +12,4 @@ __all__ = [
13
12
  "BreadcrumbBlock",
14
13
  "CreateBreadcrumbBlock",
15
14
  "BreadcrumbMarkdownNode",
16
- "BreadcrumbMarkdownBlockParams",
17
15
  ]
@@ -0,0 +1,13 @@
1
+ from notionary.blocks.markdown.markdown_node import MarkdownNode
2
+
3
+
4
+ class BreadcrumbMarkdownNode(MarkdownNode):
5
+ """
6
+ Enhanced Breadcrumb node with Pydantic integration.
7
+ Programmatic interface for creating Markdown breadcrumb blocks.
8
+ Example:
9
+ [breadcrumb]
10
+ """
11
+
12
+ def to_markdown(self) -> str:
13
+ return "[breadcrumb]"
@@ -1,6 +1,5 @@
1
1
  from notionary.blocks.bulleted_list.bulleted_list_element import BulletedListElement
2
2
  from notionary.blocks.bulleted_list.bulleted_list_markdown_node import (
3
- BulletedListMarkdownBlockParams,
4
3
  BulletedListMarkdownNode,
5
4
  )
6
5
  from notionary.blocks.bulleted_list.bulleted_list_models import (
@@ -13,5 +12,4 @@ __all__ = [
13
12
  "BulletedListItemBlock",
14
13
  "CreateBulletedListItemBlock",
15
14
  "BulletedListMarkdownNode",
16
- "BulletedListMarkdownBlockParams",
17
15
  ]
@@ -0,0 +1,20 @@
1
+ from notionary.blocks.markdown.markdown_node import MarkdownNode
2
+
3
+
4
+ class BulletedListMarkdownNode(MarkdownNode):
5
+ """
6
+ Enhanced BulletedList node with Pydantic integration.
7
+ Programmatic interface for creating Markdown bulleted list items.
8
+ Example:
9
+ - First item
10
+ - Second item
11
+ - Third item
12
+ """
13
+
14
+ texts: list[str]
15
+
16
+ def to_markdown(self) -> str:
17
+ result = []
18
+ for text in self.texts:
19
+ result.append(f"- {text}")
20
+ return "\n".join(result)
@@ -10,7 +10,6 @@ from notionary.blocks.types import BlockColor
10
10
  class BulletedListItemBlock(BaseModel):
11
11
  rich_text: list[RichTextObject]
12
12
  color: BlockColor = BlockColor.DEFAULT
13
- children: list[Block] = Field(default_factory=list)
14
13
 
15
14
 
16
15
  class CreateBulletedListItemBlock(BaseModel):
@@ -1,6 +1,5 @@
1
1
  from notionary.blocks.callout.callout_element import CalloutElement
2
2
  from notionary.blocks.callout.callout_markdown_node import (
3
- CalloutMarkdownBlockParams,
4
3
  CalloutMarkdownNode,
5
4
  )
6
5
  from notionary.blocks.callout.callout_models import CalloutBlock, CreateCalloutBlock
@@ -10,5 +9,4 @@ __all__ = [
10
9
  "CalloutBlock",
11
10
  "CreateCalloutBlock",
12
11
  "CalloutMarkdownNode",
13
- "CalloutMarkdownBlockParams",
14
12
  ]
@@ -0,0 +1,19 @@
1
+ from typing import Optional
2
+ from notionary.blocks.markdown.markdown_node import MarkdownNode
3
+
4
+
5
+ class CalloutMarkdownNode(MarkdownNode):
6
+ """
7
+ Enhanced Callout node with Pydantic integration.
8
+ Programmatic interface for creating Notion-style callout Markdown blocks.
9
+ Example: [callout](This is important "⚠️")
10
+ """
11
+
12
+ text: str
13
+ emoji: Optional[str] = None
14
+
15
+ def to_markdown(self) -> str:
16
+ if self.emoji and self.emoji != "💡":
17
+ return f'[callout]({self.text} "{self.emoji}")'
18
+ else:
19
+ return f"[callout]({self.text})"
@@ -1,6 +1,6 @@
1
1
  from typing import Literal, Optional, Union
2
2
 
3
- from pydantic import BaseModel, Field
3
+ from pydantic import BaseModel, Field, model_serializer
4
4
 
5
5
  from notionary.blocks.file.file_element_models import FileBlock
6
6
  from notionary.blocks.models import Block
@@ -23,10 +23,9 @@ IconObject = Union[EmojiIcon, FileIcon]
23
23
 
24
24
  class CalloutBlock(BaseModel):
25
25
  rich_text: list[RichTextObject]
26
- icon: Optional[IconObject] = None
27
26
  color: BlockColor = BlockColor.DEFAULT
28
- children: list[Block] = Field(default_factory=list)
29
-
27
+ icon: Optional[IconObject] = None
28
+ children: Optional[list[Block]] = None
30
29
 
31
30
  class CreateCalloutBlock(BaseModel):
32
31
  type: Literal["callout"] = "callout"
@@ -1,13 +1,11 @@
1
- from __future__ import annotations
2
-
3
1
  from typing import Optional
4
2
 
5
- from notionary.blocks.code.code_models import CodeBlock
6
- from notionary.markdown.markdown_node import MarkdownNode
3
+ from notionary.blocks.markdown.markdown_node import MarkdownNode
7
4
 
8
5
 
9
6
  class CodeMarkdownNode(MarkdownNode):
10
7
  """
8
+ Enhanced Code node with Pydantic integration.
11
9
  Programmatic interface for creating Notion-style Markdown code blocks.
12
10
  Automatically handles indentation normalization for multiline strings.
13
11
 
@@ -17,21 +15,9 @@ class CodeMarkdownNode(MarkdownNode):
17
15
  ```
18
16
  """
19
17
 
20
- def __init__(
21
- self,
22
- code: str,
23
- language: Optional[str] = None,
24
- caption: Optional[str] = None,
25
- ):
26
- self.code = code
27
- self.language = language or ""
28
- self.caption = caption
29
-
30
- @classmethod
31
- def from_params(cls, params: CodeBlock) -> CodeMarkdownNode:
32
- return cls(
33
- code=params.rich_text, language=params.language, caption=params.caption
34
- )
18
+ code: str
19
+ language: Optional[str] = None
20
+ caption: Optional[str] = None
35
21
 
36
22
  def to_markdown(self) -> str:
37
23
  lang = self.language or ""
@@ -1,11 +1,9 @@
1
1
  from notionary.blocks.column.column_element import ColumnElement
2
2
  from notionary.blocks.column.column_list_element import ColumnListElement
3
3
  from notionary.blocks.column.column_list_markdown_node import (
4
- ColumnListMarkdownBlockParams,
5
4
  ColumnListMarkdownNode,
6
5
  )
7
6
  from notionary.blocks.column.column_markdown_node import (
8
- ColumnMarkdownBlockParams,
9
7
  ColumnMarkdownNode,
10
8
  )
11
9
  from notionary.blocks.column.column_models import (
@@ -23,7 +21,5 @@ __all__ = [
23
21
  "ColumnListBlock",
24
22
  "CreateColumnListBlock",
25
23
  "ColumnMarkdownNode",
26
- "ColumnMarkdownBlockParams",
27
24
  "ColumnListMarkdownNode",
28
- "ColumnListMarkdownBlockParams",
29
25
  ]
@@ -1,19 +1,10 @@
1
- from __future__ import annotations
2
-
3
- from pydantic import BaseModel
4
-
5
1
  from notionary.blocks.column.column_markdown_node import ColumnMarkdownNode
6
- from notionary.markdown.markdown_document_model import MarkdownBlock
7
- from notionary.markdown.markdown_node import MarkdownNode
8
-
9
-
10
- class ColumnListMarkdownBlockParams(BaseModel):
11
- columns: list[list[MarkdownBlock]]
12
- model_config = {"arbitrary_types_allowed": True}
2
+ from notionary.blocks.markdown.markdown_node import MarkdownNode
13
3
 
14
4
 
15
5
  class ColumnListMarkdownNode(MarkdownNode):
16
6
  """
7
+ Enhanced Column List node with Pydantic integration.
17
8
  Programmatic interface for creating a Markdown column list container.
18
9
  This represents the `::: columns` container that holds multiple columns.
19
10
 
@@ -31,14 +22,7 @@ class ColumnListMarkdownNode(MarkdownNode):
31
22
  :::
32
23
  """
33
24
 
34
- def __init__(self, columns: list[ColumnMarkdownNode]):
35
- self.columns = columns
36
-
37
- @classmethod
38
- def from_params(
39
- cls, params: ColumnListMarkdownBlockParams
40
- ) -> ColumnListMarkdownNode:
41
- return cls(columns=params.columns)
25
+ columns: list[ColumnMarkdownNode] = []
42
26
 
43
27
  def to_markdown(self) -> str:
44
28
  if not self.columns:
@@ -1,20 +1,10 @@
1
- from __future__ import annotations
2
-
3
1
  from typing import Optional
4
-
5
- from pydantic import BaseModel
6
-
7
- from notionary.markdown.markdown_node import MarkdownNode
8
-
9
-
10
- class ColumnMarkdownBlockParams(BaseModel):
11
- children: list[MarkdownNode]
12
- width_ratio: Optional[float] = None
13
- model_config = {"arbitrary_types_allowed": True}
2
+ from notionary.blocks.markdown.markdown_node import MarkdownNode
14
3
 
15
4
 
16
5
  class ColumnMarkdownNode(MarkdownNode):
17
6
  """
7
+ Enhanced Column node with Pydantic integration.
18
8
  Programmatic interface for creating a single Markdown column block
19
9
  with nested content and optional width ratio.
20
10
 
@@ -32,15 +22,8 @@ class ColumnMarkdownNode(MarkdownNode):
32
22
  :::
33
23
  """
34
24
 
35
- def __init__(
36
- self, children: list[MarkdownNode], width_ratio: Optional[float] = None
37
- ):
38
- self.children = children
39
- self.width_ratio = width_ratio
40
-
41
- @classmethod
42
- def from_params(cls, params: ColumnMarkdownBlockParams) -> ColumnMarkdownNode:
43
- return cls(children=params.children, width_ratio=params.width_ratio)
25
+ children: list[MarkdownNode] = []
26
+ width_ratio: Optional[float] = None
44
27
 
45
28
  def to_markdown(self) -> str:
46
29
  # Start tag with optional width ratio
@@ -1,6 +1,5 @@
1
1
  from notionary.blocks.divider.divider_element import DividerElement
2
2
  from notionary.blocks.divider.divider_markdown_node import (
3
- DividerMarkdownBlockParams,
4
3
  DividerMarkdownNode,
5
4
  )
6
5
  from notionary.blocks.divider.divider_models import CreateDividerBlock, DividerBlock
@@ -10,5 +9,4 @@ __all__ = [
10
9
  "DividerBlock",
11
10
  "CreateDividerBlock",
12
11
  "DividerMarkdownNode",
13
- "DividerMarkdownBlockParams",
14
12
  ]
@@ -0,0 +1,11 @@
1
+ from notionary.blocks.markdown.markdown_node import MarkdownNode
2
+
3
+
4
+ class DividerMarkdownNode(MarkdownNode):
5
+ """
6
+ Enhanced Divider node with Pydantic integration.
7
+ Programmatic interface for creating Markdown divider lines (---).
8
+ """
9
+
10
+ def to_markdown(self) -> str:
11
+ return "---"
@@ -1,6 +1,5 @@
1
1
  from notionary.blocks.embed.embed_element import EmbedElement
2
2
  from notionary.blocks.embed.embed_markdown_node import (
3
- EmbedMarkdownBlockParams,
4
3
  EmbedMarkdownNode,
5
4
  )
6
5
  from notionary.blocks.embed.embed_models import CreateEmbedBlock, EmbedBlock
@@ -10,5 +9,4 @@ __all__ = [
10
9
  "EmbedBlock",
11
10
  "CreateEmbedBlock",
12
11
  "EmbedMarkdownNode",
13
- "EmbedMarkdownBlockParams",
14
12
  ]