notionary 0.2.18__tar.gz → 0.2.21__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 (266) hide show
  1. {notionary-0.2.18 → notionary-0.2.21}/PKG-INFO +12 -8
  2. {notionary-0.2.18 → notionary-0.2.21}/README.md +10 -7
  3. {notionary-0.2.18 → notionary-0.2.21}/notionary/__init__.py +8 -4
  4. {notionary-0.2.18 → notionary-0.2.21}/notionary/base_notion_client.py +3 -1
  5. notionary-0.2.21/notionary/blocks/__init__.py +3 -0
  6. notionary-0.2.21/notionary/blocks/_bootstrap.py +263 -0
  7. notionary-0.2.21/notionary/blocks/audio/__init__.py +13 -0
  8. notionary-0.2.21/notionary/blocks/audio/audio_element.py +90 -0
  9. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/audio/audio_markdown_node.py +3 -1
  10. notionary-0.2.21/notionary/blocks/audio/audio_models.py +10 -0
  11. notionary-0.2.21/notionary/blocks/base_block_element.py +30 -0
  12. notionary-0.2.21/notionary/blocks/bookmark/__init__.py +14 -0
  13. notionary-0.2.21/notionary/blocks/bookmark/bookmark_element.py +80 -0
  14. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/bookmark/bookmark_markdown_node.py +3 -1
  15. notionary-0.2.21/notionary/blocks/bookmark/bookmark_models.py +15 -0
  16. notionary-0.2.21/notionary/blocks/breadcrumbs/__init__.py +17 -0
  17. notionary-0.2.21/notionary/blocks/breadcrumbs/breadcrumb_element.py +39 -0
  18. notionary-0.2.21/notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +32 -0
  19. notionary-0.2.21/notionary/blocks/breadcrumbs/breadcrumb_models.py +12 -0
  20. notionary-0.2.21/notionary/blocks/bulleted_list/__init__.py +17 -0
  21. notionary-0.2.21/notionary/blocks/bulleted_list/bulleted_list_element.py +57 -0
  22. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +2 -1
  23. notionary-0.2.21/notionary/blocks/bulleted_list/bulleted_list_models.py +18 -0
  24. notionary-0.2.21/notionary/blocks/callout/__init__.py +14 -0
  25. notionary-0.2.21/notionary/blocks/callout/callout_element.py +83 -0
  26. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/callout/callout_markdown_node.py +3 -1
  27. notionary-0.2.21/notionary/blocks/callout/callout_models.py +33 -0
  28. notionary-0.2.21/notionary/blocks/child_database/__init__.py +7 -0
  29. notionary-0.2.21/notionary/blocks/child_database/child_database_models.py +19 -0
  30. notionary-0.2.21/notionary/blocks/child_page/__init__.py +9 -0
  31. notionary-0.2.21/notionary/blocks/child_page/child_page_models.py +12 -0
  32. notionary-0.2.18/notionary/blocks/shared/block_client.py → notionary-0.2.21/notionary/blocks/client.py +55 -54
  33. notionary-0.2.21/notionary/blocks/code/__init__.py +11 -0
  34. notionary-0.2.21/notionary/blocks/code/code_element.py +100 -0
  35. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/code/code_markdown_node.py +13 -13
  36. notionary-0.2.21/notionary/blocks/code/code_models.py +94 -0
  37. notionary-0.2.21/notionary/blocks/column/__init__.py +29 -0
  38. notionary-0.2.21/notionary/blocks/column/column_element.py +59 -0
  39. notionary-0.2.21/notionary/blocks/column/column_list_element.py +37 -0
  40. notionary-0.2.21/notionary/blocks/column/column_list_markdown_node.py +50 -0
  41. notionary-0.2.21/notionary/blocks/column/column_markdown_node.py +59 -0
  42. notionary-0.2.21/notionary/blocks/column/column_models.py +26 -0
  43. notionary-0.2.21/notionary/blocks/divider/__init__.py +14 -0
  44. notionary-0.2.21/notionary/blocks/divider/divider_element.py +49 -0
  45. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/divider/divider_markdown_node.py +2 -1
  46. notionary-0.2.21/notionary/blocks/divider/divider_models.py +12 -0
  47. notionary-0.2.21/notionary/blocks/embed/__init__.py +14 -0
  48. notionary-0.2.21/notionary/blocks/embed/embed_element.py +77 -0
  49. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/embed/embed_markdown_node.py +3 -1
  50. notionary-0.2.21/notionary/blocks/embed/embed_models.py +14 -0
  51. notionary-0.2.21/notionary/blocks/equation/__init__.py +14 -0
  52. notionary-0.2.21/notionary/blocks/equation/equation_element.py +80 -0
  53. notionary-0.2.21/notionary/blocks/equation/equation_element_markdown_node.py +36 -0
  54. notionary-0.2.21/notionary/blocks/equation/equation_models.py +11 -0
  55. notionary-0.2.21/notionary/blocks/file/__init__.py +25 -0
  56. notionary-0.2.21/notionary/blocks/file/file_element.py +93 -0
  57. notionary-0.2.21/notionary/blocks/file/file_element_markdown_node.py +35 -0
  58. notionary-0.2.21/notionary/blocks/file/file_element_models.py +39 -0
  59. notionary-0.2.21/notionary/blocks/heading/__init__.py +21 -0
  60. notionary-0.2.21/notionary/blocks/heading/heading_element.py +93 -0
  61. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/heading/heading_markdown_node.py +2 -1
  62. notionary-0.2.21/notionary/blocks/heading/heading_models.py +29 -0
  63. notionary-0.2.21/notionary/blocks/image_block/__init__.py +13 -0
  64. notionary-0.2.21/notionary/blocks/image_block/image_element.py +84 -0
  65. {notionary-0.2.18/notionary/blocks/image → notionary-0.2.21/notionary/blocks/image_block}/image_markdown_node.py +3 -1
  66. notionary-0.2.21/notionary/blocks/image_block/image_models.py +10 -0
  67. notionary-0.2.21/notionary/blocks/models.py +172 -0
  68. notionary-0.2.21/notionary/blocks/numbered_list/__init__.py +17 -0
  69. notionary-0.2.21/notionary/blocks/numbered_list/numbered_list_element.py +48 -0
  70. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/numbered_list/numbered_list_markdown_node.py +3 -1
  71. notionary-0.2.21/notionary/blocks/numbered_list/numbered_list_models.py +17 -0
  72. notionary-0.2.21/notionary/blocks/paragraph/__init__.py +17 -0
  73. notionary-0.2.21/notionary/blocks/paragraph/paragraph_element.py +42 -0
  74. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/paragraph/paragraph_markdown_node.py +2 -1
  75. notionary-0.2.21/notionary/blocks/paragraph/paragraph_models.py +16 -0
  76. notionary-0.2.21/notionary/blocks/pdf/__init__.py +13 -0
  77. notionary-0.2.21/notionary/blocks/pdf/pdf_element.py +91 -0
  78. notionary-0.2.21/notionary/blocks/pdf/pdf_markdown_node.py +35 -0
  79. notionary-0.2.21/notionary/blocks/pdf/pdf_models.py +11 -0
  80. notionary-0.2.21/notionary/blocks/quote/__init__.py +16 -0
  81. notionary-0.2.21/notionary/blocks/quote/quote_element.py +58 -0
  82. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/quote/quote_markdown_node.py +4 -1
  83. notionary-0.2.21/notionary/blocks/quote/quote_models.py +18 -0
  84. notionary-0.2.21/notionary/blocks/registry/__init__.py +4 -0
  85. notionary-0.2.21/notionary/blocks/registry/block_registry.py +140 -0
  86. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/registry/block_registry_builder.py +107 -59
  87. notionary-0.2.21/notionary/blocks/rich_text/__init__.py +33 -0
  88. notionary-0.2.21/notionary/blocks/rich_text/rich_text_models.py +188 -0
  89. notionary-0.2.21/notionary/blocks/rich_text/text_inline_formatter.py +125 -0
  90. notionary-0.2.21/notionary/blocks/table/__init__.py +21 -0
  91. notionary-0.2.21/notionary/blocks/table/table_element.py +124 -0
  92. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/table/table_markdown_node.py +2 -1
  93. notionary-0.2.21/notionary/blocks/table/table_models.py +28 -0
  94. notionary-0.2.21/notionary/blocks/table_of_contents/__init__.py +19 -0
  95. notionary-0.2.21/notionary/blocks/table_of_contents/table_of_contents_element.py +51 -0
  96. notionary-0.2.21/notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +35 -0
  97. notionary-0.2.21/notionary/blocks/table_of_contents/table_of_contents_models.py +18 -0
  98. notionary-0.2.21/notionary/blocks/todo/__init__.py +14 -0
  99. notionary-0.2.21/notionary/blocks/todo/todo_element.py +64 -0
  100. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/todo/todo_markdown_node.py +2 -1
  101. notionary-0.2.21/notionary/blocks/todo/todo_models.py +19 -0
  102. notionary-0.2.21/notionary/blocks/toggle/__init__.py +14 -0
  103. notionary-0.2.21/notionary/blocks/toggle/toggle_element.py +96 -0
  104. notionary-0.2.21/notionary/blocks/toggle/toggle_markdown_node.py +45 -0
  105. notionary-0.2.21/notionary/blocks/toggle/toggle_models.py +17 -0
  106. notionary-0.2.21/notionary/blocks/toggleable_heading/__init__.py +13 -0
  107. notionary-0.2.21/notionary/blocks/toggleable_heading/toggleable_heading_element.py +100 -0
  108. notionary-0.2.21/notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +51 -0
  109. notionary-0.2.21/notionary/blocks/types.py +61 -0
  110. notionary-0.2.21/notionary/blocks/video/__init__.py +13 -0
  111. notionary-0.2.21/notionary/blocks/video/video_element.py +106 -0
  112. notionary-0.2.21/notionary/blocks/video/video_element_models.py +10 -0
  113. {notionary-0.2.18 → notionary-0.2.21}/notionary/blocks/video/video_markdown_node.py +3 -1
  114. {notionary-0.2.18 → notionary-0.2.21}/notionary/database/client.py +3 -8
  115. {notionary-0.2.18 → notionary-0.2.21}/notionary/database/database.py +13 -14
  116. {notionary-0.2.18 → notionary-0.2.21}/notionary/database/database_filter_builder.py +2 -2
  117. {notionary-0.2.18 → notionary-0.2.21}/notionary/database/database_provider.py +5 -4
  118. notionary-0.2.18/notionary/models/notion_database_response.py → notionary-0.2.21/notionary/database/models.py +5 -6
  119. {notionary-0.2.18 → notionary-0.2.21}/notionary/database/notion_database.py +6 -7
  120. {notionary-0.2.18 → notionary-0.2.21}/notionary/file_upload/client.py +5 -7
  121. {notionary-0.2.18 → notionary-0.2.21}/notionary/file_upload/models.py +2 -1
  122. {notionary-0.2.18 → notionary-0.2.21}/notionary/file_upload/notion_file_upload.py +2 -3
  123. notionary-0.2.21/notionary/markdown/markdown_builder.py +722 -0
  124. notionary-0.2.21/notionary/markdown/markdown_document_model.py +228 -0
  125. {notionary-0.2.18/notionary/blocks → notionary-0.2.21/notionary/markdown}/markdown_node.py +1 -0
  126. {notionary-0.2.18 → notionary-0.2.21}/notionary/page/client.py +9 -10
  127. notionary-0.2.21/notionary/page/models.py +327 -0
  128. {notionary-0.2.18 → notionary-0.2.21}/notionary/page/notion_page.py +99 -52
  129. notionary-0.2.21/notionary/page/notion_text_length_utils.py +119 -0
  130. {notionary-0.2.18/notionary/page/content → notionary-0.2.21/notionary/page}/page_content_writer.py +88 -38
  131. notionary-0.2.21/notionary/page/reader/handler/__init__.py +17 -0
  132. notionary-0.2.21/notionary/page/reader/handler/base_block_renderer.py +44 -0
  133. notionary-0.2.21/notionary/page/reader/handler/block_processing_context.py +35 -0
  134. notionary-0.2.21/notionary/page/reader/handler/block_rendering_context.py +43 -0
  135. notionary-0.2.21/notionary/page/reader/handler/column_list_renderer.py +51 -0
  136. notionary-0.2.21/notionary/page/reader/handler/column_renderer.py +60 -0
  137. notionary-0.2.21/notionary/page/reader/handler/line_renderer.py +60 -0
  138. notionary-0.2.21/notionary/page/reader/handler/toggle_renderer.py +69 -0
  139. notionary-0.2.21/notionary/page/reader/handler/toggleable_heading_renderer.py +89 -0
  140. notionary-0.2.21/notionary/page/reader/page_content_retriever.py +69 -0
  141. {notionary-0.2.18 → notionary-0.2.21}/notionary/page/search_filter_builder.py +2 -1
  142. notionary-0.2.21/notionary/page/writer/handler/__init__.py +22 -0
  143. notionary-0.2.21/notionary/page/writer/handler/code_handler.py +100 -0
  144. notionary-0.2.21/notionary/page/writer/handler/column_handler.py +141 -0
  145. notionary-0.2.21/notionary/page/writer/handler/column_list_handler.py +139 -0
  146. notionary-0.2.21/notionary/page/writer/handler/line_handler.py +35 -0
  147. notionary-0.2.21/notionary/page/writer/handler/line_processing_context.py +54 -0
  148. notionary-0.2.21/notionary/page/writer/handler/regular_line_handler.py +92 -0
  149. notionary-0.2.21/notionary/page/writer/handler/table_handler.py +130 -0
  150. notionary-0.2.21/notionary/page/writer/handler/toggle_handler.py +153 -0
  151. notionary-0.2.21/notionary/page/writer/handler/toggleable_heading_handler.py +167 -0
  152. notionary-0.2.21/notionary/page/writer/markdown_to_notion_converter.py +76 -0
  153. {notionary-0.2.18 → notionary-0.2.21}/notionary/telemetry/__init__.py +2 -2
  154. {notionary-0.2.18 → notionary-0.2.21}/notionary/telemetry/service.py +4 -3
  155. {notionary-0.2.18 → notionary-0.2.21}/notionary/user/__init__.py +2 -2
  156. {notionary-0.2.18 → notionary-0.2.21}/notionary/user/base_notion_user.py +2 -1
  157. {notionary-0.2.18 → notionary-0.2.21}/notionary/user/client.py +2 -3
  158. {notionary-0.2.18 → notionary-0.2.21}/notionary/user/models.py +1 -0
  159. {notionary-0.2.18 → notionary-0.2.21}/notionary/user/notion_bot_user.py +4 -5
  160. {notionary-0.2.18 → notionary-0.2.21}/notionary/user/notion_user.py +3 -4
  161. {notionary-0.2.18 → notionary-0.2.21}/notionary/user/notion_user_manager.py +3 -2
  162. {notionary-0.2.18 → notionary-0.2.21}/notionary/user/notion_user_provider.py +1 -1
  163. {notionary-0.2.18 → notionary-0.2.21}/notionary/util/__init__.py +3 -2
  164. {notionary-0.2.18 → notionary-0.2.21}/notionary/util/fuzzy.py +2 -1
  165. {notionary-0.2.18 → notionary-0.2.21}/notionary/util/logging_mixin.py +2 -2
  166. {notionary-0.2.18 → notionary-0.2.21}/notionary/util/singleton_metaclass.py +1 -1
  167. {notionary-0.2.18 → notionary-0.2.21}/notionary/workspace.py +3 -2
  168. {notionary-0.2.18 → notionary-0.2.21}/pyproject.toml +5 -2
  169. notionary-0.2.18/notionary/blocks/__init__.py +0 -92
  170. notionary-0.2.18/notionary/blocks/audio/__init__.py +0 -7
  171. notionary-0.2.18/notionary/blocks/audio/audio_element.py +0 -152
  172. notionary-0.2.18/notionary/blocks/audio/audio_models.py +0 -59
  173. notionary-0.2.18/notionary/blocks/bookmark/__init__.py +0 -7
  174. notionary-0.2.18/notionary/blocks/bookmark/bookmark_element.py +0 -173
  175. notionary-0.2.18/notionary/blocks/bulleted_list/__init__.py +0 -7
  176. notionary-0.2.18/notionary/blocks/bulleted_list/bulleted_list_element.py +0 -72
  177. notionary-0.2.18/notionary/blocks/callout/__init__.py +0 -7
  178. notionary-0.2.18/notionary/blocks/callout/callout_element.py +0 -132
  179. notionary-0.2.18/notionary/blocks/code/__init__.py +0 -7
  180. notionary-0.2.18/notionary/blocks/code/code_element.py +0 -234
  181. notionary-0.2.18/notionary/blocks/column/__init__.py +0 -5
  182. notionary-0.2.18/notionary/blocks/column/column_element.py +0 -333
  183. notionary-0.2.18/notionary/blocks/column/column_models.py +0 -0
  184. notionary-0.2.18/notionary/blocks/divider/__init__.py +0 -7
  185. notionary-0.2.18/notionary/blocks/divider/divider_element.py +0 -72
  186. notionary-0.2.18/notionary/blocks/divider/divider_models.py +0 -0
  187. notionary-0.2.18/notionary/blocks/document/__init__.py +0 -7
  188. notionary-0.2.18/notionary/blocks/document/document_element.py +0 -102
  189. notionary-0.2.18/notionary/blocks/document/document_markdown_node.py +0 -31
  190. notionary-0.2.18/notionary/blocks/document/document_models.py +0 -0
  191. notionary-0.2.18/notionary/blocks/embed/__init__.py +0 -7
  192. notionary-0.2.18/notionary/blocks/embed/embed_element.py +0 -144
  193. notionary-0.2.18/notionary/blocks/embed/embed_models.py +0 -0
  194. notionary-0.2.18/notionary/blocks/heading/__init__.py +0 -7
  195. notionary-0.2.18/notionary/blocks/heading/heading_element.py +0 -98
  196. notionary-0.2.18/notionary/blocks/heading/heading_models.py +0 -0
  197. notionary-0.2.18/notionary/blocks/image/__init__.py +0 -7
  198. notionary-0.2.18/notionary/blocks/image/image_element.py +0 -151
  199. notionary-0.2.18/notionary/blocks/image/image_models.py +0 -0
  200. notionary-0.2.18/notionary/blocks/markdown_builder.py +0 -356
  201. notionary-0.2.18/notionary/blocks/mention/__init__.py +0 -7
  202. notionary-0.2.18/notionary/blocks/mention/mention_element.py +0 -229
  203. notionary-0.2.18/notionary/blocks/mention/mention_markdown_node.py +0 -38
  204. notionary-0.2.18/notionary/blocks/mention/mention_models.py +0 -0
  205. notionary-0.2.18/notionary/blocks/numbered_list/__init__.py +0 -7
  206. notionary-0.2.18/notionary/blocks/numbered_list/numbered_list_element.py +0 -73
  207. notionary-0.2.18/notionary/blocks/numbered_list/numbered_list_models.py +0 -0
  208. notionary-0.2.18/notionary/blocks/paragraph/__init__.py +0 -7
  209. notionary-0.2.18/notionary/blocks/paragraph/paragraph_element.py +0 -84
  210. notionary-0.2.18/notionary/blocks/paragraph/paragraph_models.py +0 -0
  211. notionary-0.2.18/notionary/blocks/prompts/element_prompt_builder.py +0 -83
  212. notionary-0.2.18/notionary/blocks/prompts/element_prompt_content.py +0 -41
  213. notionary-0.2.18/notionary/blocks/quote/__init__.py +0 -7
  214. notionary-0.2.18/notionary/blocks/quote/quote_element.py +0 -92
  215. notionary-0.2.18/notionary/blocks/quote/quote_models.py +0 -0
  216. notionary-0.2.18/notionary/blocks/registry/block_registry.py +0 -156
  217. notionary-0.2.18/notionary/blocks/shared/__init__.py +0 -0
  218. notionary-0.2.18/notionary/blocks/shared/models.py +0 -710
  219. notionary-0.2.18/notionary/blocks/shared/notion_block_element.py +0 -37
  220. notionary-0.2.18/notionary/blocks/shared/text_inline_formatter.py +0 -262
  221. notionary-0.2.18/notionary/blocks/shared/text_inline_formatter_new.py +0 -139
  222. notionary-0.2.18/notionary/blocks/table/__init__.py +0 -7
  223. notionary-0.2.18/notionary/blocks/table/table_element.py +0 -317
  224. notionary-0.2.18/notionary/blocks/table/table_models.py +0 -0
  225. notionary-0.2.18/notionary/blocks/todo/__init__.py +0 -7
  226. notionary-0.2.18/notionary/blocks/todo/todo_element.py +0 -121
  227. notionary-0.2.18/notionary/blocks/todo/todo_models.py +0 -0
  228. notionary-0.2.18/notionary/blocks/toggle/__init__.py +0 -4
  229. notionary-0.2.18/notionary/blocks/toggle/toggle_element.py +0 -303
  230. notionary-0.2.18/notionary/blocks/toggle/toggle_markdown_node.py +0 -35
  231. notionary-0.2.18/notionary/blocks/toggle/toggle_models.py +0 -0
  232. notionary-0.2.18/notionary/blocks/toggleable_heading/__init__.py +0 -9
  233. notionary-0.2.18/notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -270
  234. notionary-0.2.18/notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -43
  235. notionary-0.2.18/notionary/blocks/toggleable_heading/toggleable_heading_models.py +0 -0
  236. notionary-0.2.18/notionary/blocks/video/__init__.py +0 -7
  237. notionary-0.2.18/notionary/blocks/video/video_element.py +0 -182
  238. notionary-0.2.18/notionary/database/models/page_result.py +0 -10
  239. notionary-0.2.18/notionary/models/notion_block_response.py +0 -264
  240. notionary-0.2.18/notionary/models/notion_page_response.py +0 -78
  241. notionary-0.2.18/notionary/models/search_response.py +0 -0
  242. notionary-0.2.18/notionary/page/__init__.py +0 -0
  243. notionary-0.2.18/notionary/page/content/notion_text_length_utils.py +0 -87
  244. notionary-0.2.18/notionary/page/content/page_content_retriever.py +0 -52
  245. notionary-0.2.18/notionary/page/formatting/line_processor.py +0 -153
  246. notionary-0.2.18/notionary/page/formatting/markdown_to_notion_converter.py +0 -153
  247. notionary-0.2.18/notionary/page/markdown_syntax_prompt_generator.py +0 -114
  248. notionary-0.2.18/notionary/page/notion_to_markdown_converter.py +0 -179
  249. notionary-0.2.18/notionary/page/properites/property_value_extractor.py +0 -0
  250. {notionary-0.2.18 → notionary-0.2.21}/LICENSE +0 -0
  251. {notionary-0.2.18 → notionary-0.2.21}/notionary/database/__init__.py +0 -0
  252. {notionary-0.2.18 → notionary-0.2.21}/notionary/database/exceptions.py +0 -0
  253. {notionary-0.2.18 → notionary-0.2.21}/notionary/database/factory.py +0 -0
  254. {notionary-0.2.18 → notionary-0.2.21}/notionary/file_upload/__init__.py +0 -0
  255. /notionary-0.2.18/notionary/blocks/bookmark/bookmark_models.py → /notionary-0.2.21/notionary/markdown/___init__.py +0 -0
  256. /notionary-0.2.18/notionary/blocks/bulleted_list/bulleted_list_models.py → /notionary-0.2.21/notionary/markdown/makdown_document_model.py +0 -0
  257. /notionary-0.2.18/notionary/blocks/callout/callout_models.py → /notionary-0.2.21/notionary/models/notion_database_response.py +0 -0
  258. {notionary-0.2.18/notionary/page/content → notionary-0.2.21/notionary/page}/markdown_whitespace_processor.py +0 -0
  259. {notionary-0.2.18 → notionary-0.2.21}/notionary/page/property_formatter.py +0 -0
  260. /notionary-0.2.18/notionary/blocks/code/code_models.py → /notionary-0.2.21/notionary/page/reader/handler/context.py +0 -0
  261. {notionary-0.2.18 → notionary-0.2.21}/notionary/page/utils.py +0 -0
  262. {notionary-0.2.18 → notionary-0.2.21}/notionary/telemetry/views.py +0 -0
  263. {notionary-0.2.18 → notionary-0.2.21}/notionary/util/factory_decorator.py +0 -0
  264. {notionary-0.2.18 → notionary-0.2.21}/notionary/util/factory_only.py +0 -0
  265. {notionary-0.2.18 → notionary-0.2.21}/notionary/util/page_id_utils.py +0 -0
  266. {notionary-0.2.18 → notionary-0.2.21}/notionary/util/singleton.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: notionary
3
- Version: 0.2.18
3
+ Version: 0.2.21
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
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
16
  Requires-Dist: aiofiles (>=24.1.0,<25.0.0)
17
17
  Requires-Dist: httpx (>=0.28.0)
18
+ Requires-Dist: isort (>=6.0.1,<7.0.0)
18
19
  Requires-Dist: posthog (>=6.3.1,<7.0.0)
19
20
  Requires-Dist: pydantic (>=2.11.4)
20
21
  Requires-Dist: python-dotenv (>=1.1.0)
@@ -36,11 +37,11 @@ Description-Content-Type: text/markdown
36
37
  - **Rich Markdown to Notion**: Convert extended Markdown (callouts, toggles, columns) directly into beautiful Notion blocks
37
38
  - **Smart Discovery**: Find pages and databases by name with fuzzy matching - no more hunting for URLs
38
39
  - **Async-First Architecture**: Built for modern Python with full async/await support and high performance
39
- - **AI-Ready Integration**: Generate LLM system prompts and let AI agents create Notion content seamlessly
40
40
 
41
41
  ---
42
42
 
43
43
  # Quick start
44
+
44
45
  ```bash
45
46
  pip install notionary
46
47
  ```
@@ -53,29 +54,30 @@ NOTION_SECRET=YOUR_INTEGRATION_KEY
53
54
  ```
54
55
 
55
56
  ### Creating and Managing Pages 🚀
57
+
56
58
  ```python
57
59
  from notionary import NotionPage
58
60
 
59
61
  async def main():
60
62
  # Simpy find an existing page by its title
61
63
  page = await NotionPage.from_page_name("My Test Page")
62
-
64
+
63
65
  # Add rich content with custom Markdown
64
66
  content = """
65
67
  # 🚀 Generated with Notionary
66
-
68
+
67
69
  !> [💡] This page was created programmatically!
68
-
70
+
69
71
  ## Features
70
72
  - **Rich** Markdown support
71
73
  - Database integration
72
74
  - AI-ready content generation
73
-
75
+
74
76
  +++ Click to see more details
75
77
  | Notionary makes it easy to create beautiful Notion pages
76
78
  | directly from Python code with intuitive Markdown syntax.
77
79
  """
78
-
80
+
79
81
  await page.replace_content(content)
80
82
  print(f"✅ Page updated: {page.url}")
81
83
 
@@ -99,7 +101,7 @@ async def main():
99
101
  await page.set_title("🆕 New Project Entry")
100
102
  await page.set_property_value_by_name("Status", "In Progress")
101
103
  await page.set_property_value_by_name("Priority", "High")
102
-
104
+
103
105
  # find pages created in the last 7 days
104
106
  count = 0
105
107
  async for page in db.iter_pages_with_filter(
@@ -201,6 +203,7 @@ def hello_world():
201
203
  Explore the `examples/` directory for comprehensive guides:
202
204
 
203
205
  ### 🚀 Core Examples
206
+
204
207
  - [**Page Management**](examples/page_example.py) - Create, update, and manage Notion pages
205
208
  - [**Page Operations**](examples/page.py) - Advanced page manipulation and content handling
206
209
  - [**Database Operations**](examples/database.py) - Connect to and manage Notion databases
@@ -208,6 +211,7 @@ Explore the `examples/` directory for comprehensive guides:
208
211
  - [**Workspace Discovery**](examples/workspace_discovery.py) - Explore and discover your Notion workspace
209
212
 
210
213
  ### 📝 Markdown Examples
214
+
211
215
  - [**Basic Formatting**](examples/markdown/basic.py) - Text formatting, lists, and basic elements
212
216
  - [**Callouts**](examples/markdown/callout.py) - Create beautiful callout blocks with icons
213
217
  - [**Toggles**](examples/markdown/toggle.py) - Collapsible content sections
@@ -13,11 +13,11 @@
13
13
  - **Rich Markdown to Notion**: Convert extended Markdown (callouts, toggles, columns) directly into beautiful Notion blocks
14
14
  - **Smart Discovery**: Find pages and databases by name with fuzzy matching - no more hunting for URLs
15
15
  - **Async-First Architecture**: Built for modern Python with full async/await support and high performance
16
- - **AI-Ready Integration**: Generate LLM system prompts and let AI agents create Notion content seamlessly
17
16
 
18
17
  ---
19
18
 
20
19
  # Quick start
20
+
21
21
  ```bash
22
22
  pip install notionary
23
23
  ```
@@ -30,29 +30,30 @@ NOTION_SECRET=YOUR_INTEGRATION_KEY
30
30
  ```
31
31
 
32
32
  ### Creating and Managing Pages 🚀
33
+
33
34
  ```python
34
35
  from notionary import NotionPage
35
36
 
36
37
  async def main():
37
38
  # Simpy find an existing page by its title
38
39
  page = await NotionPage.from_page_name("My Test Page")
39
-
40
+
40
41
  # Add rich content with custom Markdown
41
42
  content = """
42
43
  # 🚀 Generated with Notionary
43
-
44
+
44
45
  !> [💡] This page was created programmatically!
45
-
46
+
46
47
  ## Features
47
48
  - **Rich** Markdown support
48
49
  - Database integration
49
50
  - AI-ready content generation
50
-
51
+
51
52
  +++ Click to see more details
52
53
  | Notionary makes it easy to create beautiful Notion pages
53
54
  | directly from Python code with intuitive Markdown syntax.
54
55
  """
55
-
56
+
56
57
  await page.replace_content(content)
57
58
  print(f"✅ Page updated: {page.url}")
58
59
 
@@ -76,7 +77,7 @@ async def main():
76
77
  await page.set_title("🆕 New Project Entry")
77
78
  await page.set_property_value_by_name("Status", "In Progress")
78
79
  await page.set_property_value_by_name("Priority", "High")
79
-
80
+
80
81
  # find pages created in the last 7 days
81
82
  count = 0
82
83
  async for page in db.iter_pages_with_filter(
@@ -178,6 +179,7 @@ def hello_world():
178
179
  Explore the `examples/` directory for comprehensive guides:
179
180
 
180
181
  ### 🚀 Core Examples
182
+
181
183
  - [**Page Management**](examples/page_example.py) - Create, update, and manage Notion pages
182
184
  - [**Page Operations**](examples/page.py) - Advanced page manipulation and content handling
183
185
  - [**Database Operations**](examples/database.py) - Connect to and manage Notion databases
@@ -185,6 +187,7 @@ Explore the `examples/` directory for comprehensive guides:
185
187
  - [**Workspace Discovery**](examples/workspace_discovery.py) - Explore and discover your Notion workspace
186
188
 
187
189
  ### 📝 Markdown Examples
190
+
188
191
  - [**Basic Formatting**](examples/markdown/basic.py) - Text formatting, lists, and basic elements
189
192
  - [**Callouts**](examples/markdown/callout.py) - Create beautiful callout blocks with icons
190
193
  - [**Toggles**](examples/markdown/toggle.py) - Collapsible content sections
@@ -1,9 +1,13 @@
1
- from .database import NotionDatabase, DatabaseFilterBuilder
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 .markdown.markdown_builder import MarkdownBuilder
2
8
  from .page.notion_page import NotionPage
9
+ from .user import NotionBotUser, NotionUser, NotionUserManager
3
10
  from .workspace import NotionWorkspace
4
- from .user import NotionUser, NotionUserManager, NotionBotUser
5
- from .file_upload import NotionFileUpload
6
- from .blocks.markdown_builder import MarkdownBuilder
7
11
 
8
12
  __all__ = [
9
13
  "NotionDatabase",
@@ -2,9 +2,11 @@ import asyncio
2
2
  import os
3
3
  from abc import ABC
4
4
  from enum import Enum
5
- from typing import Dict, Any, Optional, Union
5
+ from typing import Any, Dict, Optional, Union
6
+
6
7
  import httpx
7
8
  from dotenv import load_dotenv
9
+
8
10
  from notionary.util import LoggingMixin
9
11
 
10
12
  load_dotenv()
@@ -0,0 +1,3 @@
1
+ from ._bootstrap import bootstrap_blocks
2
+
3
+ __all__ = ["bootstrap_blocks"]
@@ -0,0 +1,263 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Optional, Union
4
+
5
+ _bootstrapped = False
6
+
7
+
8
+ def bootstrap_blocks() -> None:
9
+ global _bootstrapped
10
+ if _bootstrapped:
11
+ return
12
+
13
+ from notionary.blocks import (
14
+ bookmark,
15
+ breadcrumbs,
16
+ bulleted_list,
17
+ callout,
18
+ child_page,
19
+ code,
20
+ column,
21
+ divider,
22
+ embed,
23
+ equation,
24
+ file,
25
+ heading,
26
+ image_block,
27
+ models,
28
+ numbered_list,
29
+ paragraph,
30
+ quote,
31
+ table,
32
+ table_of_contents,
33
+ todo,
34
+ toggle,
35
+ toggleable_heading,
36
+ video,
37
+ )
38
+
39
+ # Collect all exports from modules
40
+ ns = {}
41
+ for m in (
42
+ bookmark,
43
+ breadcrumbs,
44
+ bulleted_list,
45
+ callout,
46
+ child_page,
47
+ code,
48
+ column,
49
+ divider,
50
+ embed,
51
+ equation,
52
+ file,
53
+ heading,
54
+ image_block,
55
+ numbered_list,
56
+ paragraph,
57
+ quote,
58
+ table,
59
+ todo,
60
+ toggle,
61
+ video,
62
+ toggleable_heading,
63
+ table_of_contents,
64
+ ):
65
+ ns.update(vars(m))
66
+
67
+ # Add missing types that are needed for model rebuilding
68
+ # These are the types that are only defined in TYPE_CHECKING in block_models
69
+ from notionary.blocks.bookmark.bookmark_models import (
70
+ BookmarkBlock,
71
+ CreateBookmarkBlock,
72
+ )
73
+ from notionary.blocks.breadcrumbs.breadcrumb_models import (
74
+ BreadcrumbBlock,
75
+ CreateBreadcrumbBlock,
76
+ )
77
+ from notionary.blocks.bulleted_list.bulleted_list_models import (
78
+ BulletedListItemBlock,
79
+ CreateBulletedListItemBlock,
80
+ )
81
+ from notionary.blocks.callout.callout_models import CalloutBlock, CreateCalloutBlock
82
+ from notionary.blocks.child_page.child_page_models import (
83
+ ChildPageBlock,
84
+ CreateChildPageBlock,
85
+ )
86
+ from notionary.blocks.code.code_models import CodeBlock, CreateCodeBlock
87
+ from notionary.blocks.column.column_models import (
88
+ ColumnBlock,
89
+ ColumnListBlock,
90
+ CreateColumnBlock,
91
+ CreateColumnListBlock,
92
+ )
93
+ from notionary.blocks.divider.divider_models import CreateDividerBlock, DividerBlock
94
+ from notionary.blocks.embed.embed_models import CreateEmbedBlock, EmbedBlock
95
+ from notionary.blocks.equation.equation_models import (
96
+ CreateEquationBlock,
97
+ EquationBlock,
98
+ )
99
+ from notionary.blocks.file.file_element_models import CreateFileBlock, FileBlock
100
+ from notionary.blocks.heading.heading_models import (
101
+ CreateHeading1Block,
102
+ CreateHeading2Block,
103
+ CreateHeading3Block,
104
+ HeadingBlock,
105
+ )
106
+ from notionary.blocks.image_block.image_models import CreateImageBlock
107
+ from notionary.blocks.numbered_list.numbered_list_models import (
108
+ CreateNumberedListItemBlock,
109
+ NumberedListItemBlock,
110
+ )
111
+ from notionary.blocks.paragraph.paragraph_models import (
112
+ CreateParagraphBlock,
113
+ ParagraphBlock,
114
+ )
115
+ from notionary.blocks.pdf.pdf_models import CreatePdfBlock
116
+ from notionary.blocks.quote.quote_models import CreateQuoteBlock, QuoteBlock
117
+ from notionary.blocks.table.table_models import TableBlock, TableRowBlock
118
+ from notionary.blocks.table_of_contents.table_of_contents_models import (
119
+ CreateTableOfContentsBlock,
120
+ TableOfContentsBlock,
121
+ )
122
+ from notionary.blocks.todo.todo_models import CreateToDoBlock, ToDoBlock
123
+ from notionary.blocks.toggle.toggle_models import CreateToggleBlock, ToggleBlock
124
+ from notionary.blocks.types import BlockType
125
+ from notionary.blocks.video.video_element_models import CreateVideoBlock
126
+
127
+ # Define the Union types that are needed for model rebuilding
128
+ BlockCreateRequest = Union[
129
+ CreateBookmarkBlock,
130
+ CreateBreadcrumbBlock,
131
+ CreateBulletedListItemBlock,
132
+ CreateCalloutBlock,
133
+ CreateChildPageBlock,
134
+ CreateCodeBlock,
135
+ CreateColumnListBlock,
136
+ CreateColumnBlock,
137
+ CreateDividerBlock,
138
+ CreateEmbedBlock,
139
+ CreateEquationBlock,
140
+ CreateFileBlock,
141
+ CreateHeading1Block,
142
+ CreateHeading2Block,
143
+ CreateHeading3Block,
144
+ CreateImageBlock,
145
+ CreateNumberedListItemBlock,
146
+ CreateParagraphBlock,
147
+ CreateQuoteBlock,
148
+ CreateToDoBlock,
149
+ CreateToggleBlock,
150
+ CreateVideoBlock,
151
+ CreateTableOfContentsBlock,
152
+ CreatePdfBlock,
153
+ ]
154
+
155
+ BlockCreateResult = Optional[Union[list[BlockCreateRequest], BlockCreateRequest]]
156
+
157
+ # Add all block types to namespace
158
+ ns.update(
159
+ {
160
+ "BlockType": BlockType,
161
+ "BookmarkBlock": BookmarkBlock,
162
+ "CreateBookmarkBlock": CreateBookmarkBlock,
163
+ "BreadcrumbBlock": BreadcrumbBlock,
164
+ "CreateBreadcrumbBlock": CreateBreadcrumbBlock,
165
+ "BulletedListItemBlock": BulletedListItemBlock,
166
+ "CreateBulletedListItemBlock": CreateBulletedListItemBlock,
167
+ "CalloutBlock": CalloutBlock,
168
+ "CreateCalloutBlock": CreateCalloutBlock,
169
+ "ChildPageBlock": ChildPageBlock,
170
+ "CreateChildPageBlock": CreateChildPageBlock,
171
+ "CodeBlock": CodeBlock,
172
+ "CreateCodeBlock": CreateCodeBlock,
173
+ "ColumnBlock": ColumnBlock,
174
+ "ColumnListBlock": ColumnListBlock,
175
+ "CreateColumnBlock": CreateColumnBlock,
176
+ "CreateColumnListBlock": CreateColumnListBlock,
177
+ "DividerBlock": DividerBlock,
178
+ "CreateDividerBlock": CreateDividerBlock,
179
+ "EmbedBlock": EmbedBlock,
180
+ "CreateEmbedBlock": CreateEmbedBlock,
181
+ "EquationBlock": EquationBlock,
182
+ "CreateEquationBlock": CreateEquationBlock,
183
+ "FileBlock": FileBlock,
184
+ "CreateFileBlock": CreateFileBlock,
185
+ "HeadingBlock": HeadingBlock,
186
+ "CreateHeading1Block": CreateHeading1Block,
187
+ "CreateHeading2Block": CreateHeading2Block,
188
+ "CreateHeading3Block": CreateHeading3Block,
189
+ "CreateImageBlock": CreateImageBlock,
190
+ "NumberedListItemBlock": NumberedListItemBlock,
191
+ "CreateNumberedListItemBlock": CreateNumberedListItemBlock,
192
+ "ParagraphBlock": ParagraphBlock,
193
+ "CreateParagraphBlock": CreateParagraphBlock,
194
+ "QuoteBlock": QuoteBlock,
195
+ "CreateQuoteBlock": CreateQuoteBlock,
196
+ "TableBlock": TableBlock,
197
+ "TableRowBlock": TableRowBlock,
198
+ "ToDoBlock": ToDoBlock,
199
+ "CreateToDoBlock": CreateToDoBlock,
200
+ "ToggleBlock": ToggleBlock,
201
+ "CreateToggleBlock": CreateToggleBlock,
202
+ "CreateVideoBlock": CreateVideoBlock,
203
+ "TableOfContentsBlock": TableOfContentsBlock,
204
+ "CreateTableOfContentsBlock": CreateTableOfContentsBlock,
205
+ # Add the Union types
206
+ "BlockCreateRequest": BlockCreateRequest,
207
+ "BlockCreateResult": BlockCreateResult,
208
+ }
209
+ )
210
+
211
+ # Now rebuild with complete namespace
212
+ models.Block.model_rebuild(_types_namespace=ns)
213
+ models.BlockChildrenResponse.model_rebuild(_types_namespace=ns)
214
+
215
+ # Rebuild all individual block models
216
+ BookmarkBlock.model_rebuild()
217
+ BreadcrumbBlock.model_rebuild()
218
+ BulletedListItemBlock.model_rebuild()
219
+ CalloutBlock.model_rebuild()
220
+ ChildPageBlock.model_rebuild()
221
+ CodeBlock.model_rebuild()
222
+ ColumnBlock.model_rebuild()
223
+ ColumnListBlock.model_rebuild()
224
+ DividerBlock.model_rebuild()
225
+ EmbedBlock.model_rebuild()
226
+ EquationBlock.model_rebuild()
227
+ FileBlock.model_rebuild()
228
+ HeadingBlock.model_rebuild()
229
+ NumberedListItemBlock.model_rebuild()
230
+ ParagraphBlock.model_rebuild()
231
+ QuoteBlock.model_rebuild()
232
+ TableBlock.model_rebuild()
233
+ TableRowBlock.model_rebuild()
234
+ ToDoBlock.model_rebuild()
235
+ ToggleBlock.model_rebuild()
236
+ TableOfContentsBlock.model_rebuild()
237
+
238
+ # Rebuild create models
239
+ CreateBookmarkBlock.model_rebuild()
240
+ CreateBreadcrumbBlock.model_rebuild()
241
+ CreateBulletedListItemBlock.model_rebuild()
242
+ CreateCalloutBlock.model_rebuild()
243
+ CreateChildPageBlock.model_rebuild()
244
+ CreateCodeBlock.model_rebuild()
245
+ CreateColumnListBlock.model_rebuild()
246
+ CreateColumnBlock.model_rebuild()
247
+ CreateDividerBlock.model_rebuild()
248
+ CreateEmbedBlock.model_rebuild()
249
+ CreateEquationBlock.model_rebuild()
250
+ CreateFileBlock.model_rebuild()
251
+ CreateHeading1Block.model_rebuild()
252
+ CreateHeading2Block.model_rebuild()
253
+ CreateHeading3Block.model_rebuild()
254
+ CreateImageBlock.model_rebuild()
255
+ CreateNumberedListItemBlock.model_rebuild()
256
+ CreateParagraphBlock.model_rebuild()
257
+ CreateQuoteBlock.model_rebuild()
258
+ CreateToDoBlock.model_rebuild()
259
+ CreateToggleBlock.model_rebuild()
260
+ CreateVideoBlock.model_rebuild()
261
+ CreateTableOfContentsBlock.model_rebuild()
262
+
263
+ _bootstrapped = True
@@ -0,0 +1,13 @@
1
+ from notionary.blocks.audio.audio_element import AudioElement
2
+ from notionary.blocks.audio.audio_markdown_node import (
3
+ AudioMarkdownBlockParams,
4
+ AudioMarkdownNode,
5
+ )
6
+ from notionary.blocks.audio.audio_models import CreateAudioBlock
7
+
8
+ __all__ = [
9
+ "AudioElement",
10
+ "CreateAudioBlock",
11
+ "AudioMarkdownNode",
12
+ "AudioMarkdownBlockParams",
13
+ ]
@@ -0,0 +1,90 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from typing import Optional
5
+
6
+ from notionary.blocks.audio.audio_models import CreateAudioBlock
7
+ from notionary.blocks.base_block_element import BaseBlockElement
8
+ from notionary.blocks.file.file_element_models import ExternalFile, FileBlock, FileType
9
+ from notionary.blocks.models import Block, BlockCreateResult, BlockType
10
+ from notionary.blocks.rich_text.rich_text_models import RichTextObject
11
+ from notionary.blocks.rich_text.text_inline_formatter import TextInlineFormatter
12
+
13
+
14
+ class AudioElement(BaseBlockElement):
15
+ """
16
+ Handles conversion between Markdown audio embeds and Notion audio blocks.
17
+
18
+ Markdown audio syntax:
19
+ - [audio](https://example.com/audio.mp3) - Simple audio embed
20
+ - [audio](https://example.com/audio.mp3 "Caption text") - Audio with optional caption
21
+
22
+ Where:
23
+ - URL is the required audio file URL
24
+ - Caption is optional descriptive text (enclosed in quotes)
25
+ """
26
+
27
+ URL_PATTERN = r"(https?://[^\s\"]+)"
28
+ CAPTION_PATTERN = r'(?:\s+"([^"]+)")?'
29
+ PATTERN = re.compile(r"^\[audio\]\(" + URL_PATTERN + CAPTION_PATTERN + r"\)$")
30
+
31
+ SUPPORTED_EXTENSIONS = {".mp3", ".wav", ".ogg", ".oga", ".m4a"}
32
+
33
+ @classmethod
34
+ def match_notion(cls, block: Block) -> bool:
35
+ """Check if this element can handle the given Notion block."""
36
+ return block.type == BlockType.AUDIO
37
+
38
+ @classmethod
39
+ def markdown_to_notion(cls, text: str) -> BlockCreateResult:
40
+ """Convert markdown audio embed to Notion audio block (or return None if not matching)."""
41
+ match = cls.PATTERN.match(text.strip())
42
+ if not match:
43
+ return None
44
+ url = match.group(1)
45
+
46
+ if not cls._is_likely_audio_url(url):
47
+ return None
48
+ caption_text = match.group(2)
49
+
50
+ # Create caption rich text objects
51
+ caption_objects = []
52
+ if caption_text:
53
+ caption_rt = RichTextObject.from_plain_text(caption_text)
54
+ caption_objects = [caption_rt]
55
+
56
+ audio_content = FileBlock(
57
+ type=FileType.EXTERNAL,
58
+ external=ExternalFile(url=url),
59
+ caption=caption_objects,
60
+ )
61
+
62
+ return CreateAudioBlock(audio=audio_content)
63
+
64
+ @classmethod
65
+ def notion_to_markdown(cls, block: Block) -> Optional[str]:
66
+ """Convert Notion audio block to markdown audio embed."""
67
+ if block.type != BlockType.AUDIO or block.audio is None:
68
+ return None
69
+
70
+ audio = block.audio
71
+
72
+ # Only handle external audio
73
+ if audio.type != FileType.EXTERNAL or audio.external is None:
74
+ return None
75
+ url = audio.external.url
76
+ if not url:
77
+ return None
78
+
79
+ # Extract caption
80
+ captions = audio.caption or []
81
+ if captions:
82
+ # use TextInlineFormatter instead of manual extraction
83
+ caption_text = TextInlineFormatter.extract_text_with_formatting(captions)
84
+ return f'[audio]({url} "{caption_text}")'
85
+
86
+ return f"[audio]({url})"
87
+
88
+ @classmethod
89
+ def _is_likely_audio_url(cls, url: str) -> bool:
90
+ return any(url.lower().endswith(ext) for ext in cls.SUPPORTED_EXTENSIONS)
@@ -1,8 +1,10 @@
1
1
  from __future__ import annotations
2
+
2
3
  from typing import Optional
4
+
3
5
  from pydantic import BaseModel
4
6
 
5
- from notionary.blocks.markdown_node import MarkdownNode
7
+ from notionary.markdown.markdown_node import MarkdownNode
6
8
 
7
9
 
8
10
  class AudioMarkdownBlockParams(BaseModel):
@@ -0,0 +1,10 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from notionary.blocks.file.file_element_models import FileBlock
6
+
7
+
8
+ class CreateAudioBlock(BaseModel):
9
+ type: Literal["audio"] = "audio"
10
+ audio: FileBlock
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC
4
+ from typing import Optional
5
+
6
+ from notionary.blocks.models import Block, BlockCreateResult
7
+
8
+
9
+ class BaseBlockElement(ABC):
10
+ """Base class for elements that can be converted between Markdown and Notion."""
11
+
12
+ @classmethod
13
+ def markdown_to_notion(cls, text: str) -> BlockCreateResult:
14
+ """
15
+ Convert markdown to Notion block content.
16
+
17
+ Returns:
18
+ - BlockContent: Single block content (e.g., ToDoBlock, ParagraphBlock)
19
+ - list[BlockContent]: Multiple block contents
20
+ - None: Cannot convert this markdown
21
+ """
22
+
23
+ @classmethod
24
+ def notion_to_markdown(cls, block: Block) -> Optional[str]:
25
+ """Convert Notion block to markdown."""
26
+
27
+ @classmethod
28
+ def match_notion(cls, block: Block) -> bool:
29
+ """Check if this element can handle the given Notion block."""
30
+ return bool(cls.notion_to_markdown(block)) # Now calls the class's version
@@ -0,0 +1,14 @@
1
+ from notionary.blocks.bookmark.bookmark_element import BookmarkElement
2
+ from notionary.blocks.bookmark.bookmark_markdown_node import (
3
+ BookmarkMarkdownBlockParams,
4
+ BookmarkMarkdownNode,
5
+ )
6
+ from notionary.blocks.bookmark.bookmark_models import BookmarkBlock, CreateBookmarkBlock
7
+
8
+ __all__ = [
9
+ "BookmarkElement",
10
+ "BookmarkBlock",
11
+ "CreateBookmarkBlock",
12
+ "BookmarkMarkdownNode",
13
+ "BookmarkMarkdownBlockParams",
14
+ ]