notionary 0.2.26__py3-none-any.whl → 0.2.28__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. notionary/__init__.py +5 -20
  2. notionary/blocks/client.py +87 -215
  3. notionary/blocks/enums.py +167 -0
  4. notionary/blocks/rich_text/markdown_rich_text_converter.py +266 -0
  5. notionary/blocks/rich_text/models.py +164 -0
  6. notionary/blocks/rich_text/name_id_resolver/__init__.py +11 -0
  7. notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
  8. notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
  9. notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
  10. notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
  11. notionary/blocks/rich_text/rich_text_markdown_converter.py +132 -0
  12. notionary/blocks/rich_text/rich_text_patterns.py +39 -0
  13. notionary/blocks/schemas.py +746 -0
  14. notionary/comments/client.py +52 -187
  15. notionary/comments/factory.py +40 -0
  16. notionary/comments/models.py +5 -127
  17. notionary/comments/schemas.py +240 -0
  18. notionary/comments/service.py +34 -0
  19. notionary/data_source/http/client.py +11 -0
  20. notionary/data_source/http/data_source_instance_client.py +94 -0
  21. notionary/data_source/properties/models.py +406 -0
  22. notionary/data_source/query/builder.py +429 -0
  23. notionary/data_source/query/resolver.py +114 -0
  24. notionary/data_source/query/schema.py +304 -0
  25. notionary/data_source/query/validator.py +73 -0
  26. notionary/data_source/schemas.py +27 -0
  27. notionary/data_source/service.py +353 -0
  28. notionary/database/client.py +30 -135
  29. notionary/database/database_metadata_update_client.py +19 -0
  30. notionary/database/schemas.py +29 -0
  31. notionary/database/service.py +169 -0
  32. notionary/exceptions/__init__.py +33 -0
  33. notionary/exceptions/api.py +41 -0
  34. notionary/exceptions/base.py +2 -0
  35. notionary/exceptions/block_parsing.py +16 -0
  36. notionary/exceptions/data_source/__init__.py +6 -0
  37. notionary/exceptions/data_source/builder.py +182 -0
  38. notionary/exceptions/data_source/properties.py +34 -0
  39. notionary/exceptions/properties.py +58 -0
  40. notionary/exceptions/search.py +33 -0
  41. notionary/file_upload/client.py +18 -30
  42. notionary/file_upload/models.py +7 -8
  43. notionary/file_upload/{notion_file_upload.py → service.py} +29 -64
  44. notionary/http/client.py +205 -0
  45. notionary/http/models.py +49 -0
  46. notionary/page/blocks/client.py +1 -0
  47. notionary/page/content/factory.py +68 -0
  48. notionary/page/content/markdown/__init__.py +5 -0
  49. notionary/page/content/markdown/builder.py +304 -0
  50. notionary/page/content/markdown/nodes/__init__.py +54 -0
  51. notionary/page/content/markdown/nodes/audio.py +23 -0
  52. notionary/page/content/markdown/nodes/base.py +12 -0
  53. notionary/page/content/markdown/nodes/bookmark.py +25 -0
  54. notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
  55. notionary/page/content/markdown/nodes/bulleted_list.py +18 -0
  56. notionary/page/content/markdown/nodes/callout.py +32 -0
  57. notionary/page/content/markdown/nodes/code.py +30 -0
  58. notionary/page/content/markdown/nodes/columns.py +51 -0
  59. notionary/page/content/markdown/nodes/divider.py +14 -0
  60. notionary/page/content/markdown/nodes/embed.py +23 -0
  61. notionary/page/content/markdown/nodes/equation.py +19 -0
  62. notionary/page/content/markdown/nodes/file.py +23 -0
  63. notionary/page/content/markdown/nodes/heading.py +16 -0
  64. notionary/page/content/markdown/nodes/image.py +23 -0
  65. notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
  66. notionary/page/content/markdown/nodes/numbered_list.py +15 -0
  67. notionary/page/content/markdown/nodes/paragraph.py +14 -0
  68. notionary/page/content/markdown/nodes/pdf.py +23 -0
  69. notionary/page/content/markdown/nodes/quote.py +15 -0
  70. notionary/page/content/markdown/nodes/space.py +14 -0
  71. notionary/page/content/markdown/nodes/table.py +45 -0
  72. notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
  73. notionary/page/content/markdown/nodes/todo.py +22 -0
  74. notionary/page/content/markdown/nodes/toggle.py +28 -0
  75. notionary/page/content/markdown/nodes/toggleable_heading.py +35 -0
  76. notionary/page/content/markdown/nodes/video.py +23 -0
  77. notionary/page/content/parser/context.py +49 -0
  78. notionary/page/content/parser/factory.py +219 -0
  79. notionary/page/content/parser/parsers/__init__.py +60 -0
  80. notionary/page/content/parser/parsers/audio.py +40 -0
  81. notionary/page/content/parser/parsers/base.py +30 -0
  82. notionary/page/content/parser/parsers/bookmark.py +33 -0
  83. notionary/page/content/parser/parsers/breadcrumb.py +33 -0
  84. notionary/page/content/parser/parsers/bulleted_list.py +41 -0
  85. notionary/page/content/parser/parsers/callout.py +129 -0
  86. notionary/page/content/parser/parsers/caption.py +55 -0
  87. notionary/page/content/parser/parsers/code.py +81 -0
  88. notionary/page/content/parser/parsers/column.py +117 -0
  89. notionary/page/content/parser/parsers/column_list.py +81 -0
  90. notionary/page/content/parser/parsers/divider.py +33 -0
  91. notionary/page/content/parser/parsers/embed.py +33 -0
  92. notionary/page/content/parser/parsers/equation.py +65 -0
  93. notionary/page/content/parser/parsers/file.py +42 -0
  94. notionary/page/content/parser/parsers/heading.py +58 -0
  95. notionary/page/content/parser/parsers/image.py +42 -0
  96. notionary/page/content/parser/parsers/numbered_list.py +45 -0
  97. notionary/page/content/parser/parsers/paragraph.py +36 -0
  98. notionary/page/content/parser/parsers/pdf.py +42 -0
  99. notionary/page/content/parser/parsers/quote.py +65 -0
  100. notionary/page/content/parser/parsers/space.py +35 -0
  101. notionary/page/content/parser/parsers/table.py +144 -0
  102. notionary/page/content/parser/parsers/table_of_contents.py +32 -0
  103. notionary/page/content/parser/parsers/todo.py +58 -0
  104. notionary/page/content/parser/parsers/toggle.py +127 -0
  105. notionary/page/content/parser/parsers/toggleable_heading.py +150 -0
  106. notionary/page/content/parser/parsers/video.py +42 -0
  107. notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
  108. notionary/page/content/parser/post_processing/handlers/rich_text_length.py +93 -0
  109. notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +93 -0
  110. notionary/page/content/parser/post_processing/port.py +9 -0
  111. notionary/page/content/parser/post_processing/service.py +16 -0
  112. notionary/page/content/parser/pre_processsing/handlers/__init__.py +9 -0
  113. notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +80 -0
  114. notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
  115. notionary/page/content/parser/pre_processsing/handlers/whitespace.py +68 -0
  116. notionary/page/content/parser/pre_processsing/service.py +15 -0
  117. notionary/page/content/parser/service.py +69 -0
  118. notionary/page/content/renderer/context.py +48 -0
  119. notionary/page/content/renderer/factory.py +240 -0
  120. notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
  121. notionary/page/content/renderer/post_processing/handlers/numbered_list_placeholdere.py +62 -0
  122. notionary/page/content/renderer/post_processing/port.py +7 -0
  123. notionary/page/content/renderer/post_processing/service.py +15 -0
  124. notionary/page/content/renderer/renderers/__init__.py +57 -0
  125. notionary/page/content/renderer/renderers/audio.py +31 -0
  126. notionary/page/content/renderer/renderers/base.py +31 -0
  127. notionary/page/content/renderer/renderers/bookmark.py +25 -0
  128. notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
  129. notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
  130. notionary/page/content/renderer/renderers/callout.py +65 -0
  131. notionary/page/content/renderer/renderers/captioned_block.py +58 -0
  132. notionary/page/content/renderer/renderers/code.py +34 -0
  133. notionary/page/content/renderer/renderers/column.py +44 -0
  134. notionary/page/content/renderer/renderers/column_list.py +31 -0
  135. notionary/page/content/renderer/renderers/divider.py +22 -0
  136. notionary/page/content/renderer/renderers/embed.py +25 -0
  137. notionary/page/content/renderer/renderers/equation.py +37 -0
  138. notionary/page/content/renderer/renderers/fallback.py +24 -0
  139. notionary/page/content/renderer/renderers/file.py +40 -0
  140. notionary/page/content/renderer/renderers/heading.py +69 -0
  141. notionary/page/content/renderer/renderers/image.py +31 -0
  142. notionary/page/content/renderer/renderers/numbered_list.py +41 -0
  143. notionary/page/content/renderer/renderers/paragraph.py +40 -0
  144. notionary/page/content/renderer/renderers/pdf.py +31 -0
  145. notionary/page/content/renderer/renderers/quote.py +49 -0
  146. notionary/page/content/renderer/renderers/table.py +115 -0
  147. notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
  148. notionary/page/content/renderer/renderers/table_row.py +17 -0
  149. notionary/page/content/renderer/renderers/todo.py +56 -0
  150. notionary/page/content/renderer/renderers/toggle.py +53 -0
  151. notionary/page/content/renderer/renderers/toggleable_heading.py +78 -0
  152. notionary/page/content/renderer/renderers/video.py +31 -0
  153. notionary/page/content/renderer/service.py +50 -0
  154. notionary/page/content/service.py +65 -0
  155. notionary/page/content/syntax/models.py +68 -0
  156. notionary/page/content/syntax/service.py +453 -0
  157. notionary/page/page_context.py +7 -16
  158. notionary/page/page_http_client.py +15 -0
  159. notionary/page/page_metadata_update_client.py +19 -0
  160. notionary/page/properties/client.py +144 -0
  161. notionary/page/properties/factory.py +26 -0
  162. notionary/page/properties/models.py +307 -0
  163. notionary/page/properties/service.py +257 -0
  164. notionary/page/schemas.py +13 -0
  165. notionary/page/service.py +222 -0
  166. notionary/shared/entity/client.py +29 -0
  167. notionary/shared/entity/dto_parsers.py +53 -0
  168. notionary/shared/entity/entity_metadata_update_client.py +41 -0
  169. notionary/shared/entity/schemas.py +45 -0
  170. notionary/shared/entity/service.py +171 -0
  171. notionary/shared/models/cover.py +20 -0
  172. notionary/shared/models/file.py +21 -0
  173. notionary/shared/models/icon.py +28 -0
  174. notionary/shared/models/parent.py +41 -0
  175. notionary/shared/properties/type.py +30 -0
  176. notionary/user/__init__.py +4 -8
  177. notionary/user/base.py +89 -0
  178. notionary/user/bot.py +70 -0
  179. notionary/user/client.py +22 -111
  180. notionary/user/person.py +41 -0
  181. notionary/user/schemas.py +67 -0
  182. notionary/user/service.py +65 -0
  183. notionary/utils/async_retry.py +39 -0
  184. notionary/utils/date.py +51 -0
  185. notionary/utils/fuzzy.py +56 -0
  186. notionary/{util/logging_mixin.py → utils/mixins/logging.py} +4 -16
  187. notionary/utils/pagination.py +50 -0
  188. notionary/utils/singleton.py +13 -0
  189. notionary/utils/uuid_utils.py +20 -0
  190. notionary/workspace/__init__.py +3 -0
  191. notionary/workspace/client.py +62 -0
  192. notionary/workspace/query/builder.py +60 -0
  193. notionary/workspace/query/models.py +60 -0
  194. notionary/workspace/query/service.py +93 -0
  195. notionary/workspace/schemas.py +21 -0
  196. notionary/workspace/service.py +116 -0
  197. {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info}/METADATA +54 -49
  198. notionary-0.2.28.dist-info/RECORD +200 -0
  199. {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info}/WHEEL +1 -1
  200. {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info/licenses}/LICENSE +9 -9
  201. notionary/base_notion_client.py +0 -219
  202. notionary/blocks/__init__.py +0 -5
  203. notionary/blocks/_bootstrap.py +0 -271
  204. notionary/blocks/audio/__init__.py +0 -11
  205. notionary/blocks/audio/audio_element.py +0 -158
  206. notionary/blocks/audio/audio_markdown_node.py +0 -24
  207. notionary/blocks/audio/audio_models.py +0 -10
  208. notionary/blocks/base_block_element.py +0 -42
  209. notionary/blocks/bookmark/__init__.py +0 -12
  210. notionary/blocks/bookmark/bookmark_element.py +0 -83
  211. notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
  212. notionary/blocks/bookmark/bookmark_models.py +0 -15
  213. notionary/blocks/breadcrumbs/__init__.py +0 -15
  214. notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
  215. notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
  216. notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
  217. notionary/blocks/bulleted_list/__init__.py +0 -15
  218. notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
  219. notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
  220. notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
  221. notionary/blocks/callout/__init__.py +0 -12
  222. notionary/blocks/callout/callout_element.py +0 -99
  223. notionary/blocks/callout/callout_markdown_node.py +0 -19
  224. notionary/blocks/callout/callout_models.py +0 -33
  225. notionary/blocks/child_database/__init__.py +0 -14
  226. notionary/blocks/child_database/child_database_element.py +0 -59
  227. notionary/blocks/child_database/child_database_models.py +0 -12
  228. notionary/blocks/child_page/__init__.py +0 -9
  229. notionary/blocks/child_page/child_page_element.py +0 -94
  230. notionary/blocks/child_page/child_page_models.py +0 -12
  231. notionary/blocks/code/__init__.py +0 -11
  232. notionary/blocks/code/code_element.py +0 -149
  233. notionary/blocks/code/code_markdown_node.py +0 -80
  234. notionary/blocks/code/code_models.py +0 -94
  235. notionary/blocks/column/__init__.py +0 -25
  236. notionary/blocks/column/column_element.py +0 -65
  237. notionary/blocks/column/column_list_element.py +0 -52
  238. notionary/blocks/column/column_list_markdown_node.py +0 -34
  239. notionary/blocks/column/column_markdown_node.py +0 -42
  240. notionary/blocks/column/column_models.py +0 -26
  241. notionary/blocks/divider/__init__.py +0 -12
  242. notionary/blocks/divider/divider_element.py +0 -41
  243. notionary/blocks/divider/divider_markdown_node.py +0 -11
  244. notionary/blocks/divider/divider_models.py +0 -12
  245. notionary/blocks/embed/__init__.py +0 -12
  246. notionary/blocks/embed/embed_element.py +0 -98
  247. notionary/blocks/embed/embed_markdown_node.py +0 -19
  248. notionary/blocks/embed/embed_models.py +0 -14
  249. notionary/blocks/equation/__init__.py +0 -13
  250. notionary/blocks/equation/equation_element.py +0 -133
  251. notionary/blocks/equation/equation_element_markdown_node.py +0 -23
  252. notionary/blocks/equation/equation_models.py +0 -11
  253. notionary/blocks/file/__init__.py +0 -23
  254. notionary/blocks/file/file_element.py +0 -133
  255. notionary/blocks/file/file_element_markdown_node.py +0 -24
  256. notionary/blocks/file/file_element_models.py +0 -39
  257. notionary/blocks/heading/__init__.py +0 -19
  258. notionary/blocks/heading/heading_element.py +0 -112
  259. notionary/blocks/heading/heading_markdown_node.py +0 -16
  260. notionary/blocks/heading/heading_models.py +0 -29
  261. notionary/blocks/image_block/__init__.py +0 -11
  262. notionary/blocks/image_block/image_element.py +0 -130
  263. notionary/blocks/image_block/image_markdown_node.py +0 -25
  264. notionary/blocks/image_block/image_models.py +0 -10
  265. notionary/blocks/markdown/markdown_builder.py +0 -525
  266. notionary/blocks/markdown/markdown_document_model.py +0 -0
  267. notionary/blocks/markdown/markdown_node.py +0 -25
  268. notionary/blocks/mixins/captions/__init__.py +0 -4
  269. notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
  270. notionary/blocks/mixins/captions/caption_mixin.py +0 -92
  271. notionary/blocks/mixins/file_upload/__init__.py +0 -3
  272. notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
  273. notionary/blocks/models.py +0 -174
  274. notionary/blocks/numbered_list/__init__.py +0 -16
  275. notionary/blocks/numbered_list/numbered_list_element.py +0 -65
  276. notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
  277. notionary/blocks/numbered_list/numbered_list_models.py +0 -17
  278. notionary/blocks/paragraph/__init__.py +0 -15
  279. notionary/blocks/paragraph/paragraph_element.py +0 -58
  280. notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
  281. notionary/blocks/paragraph/paragraph_models.py +0 -16
  282. notionary/blocks/pdf/__init__.py +0 -11
  283. notionary/blocks/pdf/pdf_element.py +0 -146
  284. notionary/blocks/pdf/pdf_markdown_node.py +0 -24
  285. notionary/blocks/pdf/pdf_models.py +0 -11
  286. notionary/blocks/quote/__init__.py +0 -14
  287. notionary/blocks/quote/quote_element.py +0 -75
  288. notionary/blocks/quote/quote_markdown_node.py +0 -16
  289. notionary/blocks/quote/quote_models.py +0 -18
  290. notionary/blocks/registry/__init__.py +0 -3
  291. notionary/blocks/registry/block_registry.py +0 -150
  292. notionary/blocks/rich_text/__init__.py +0 -33
  293. notionary/blocks/rich_text/rich_text_models.py +0 -221
  294. notionary/blocks/rich_text/text_inline_formatter.py +0 -456
  295. notionary/blocks/syntax_prompt_builder.py +0 -137
  296. notionary/blocks/table/__init__.py +0 -19
  297. notionary/blocks/table/table_element.py +0 -225
  298. notionary/blocks/table/table_markdown_node.py +0 -42
  299. notionary/blocks/table/table_models.py +0 -28
  300. notionary/blocks/table_of_contents/__init__.py +0 -17
  301. notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
  302. notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
  303. notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
  304. notionary/blocks/todo/__init__.py +0 -12
  305. notionary/blocks/todo/todo_element.py +0 -81
  306. notionary/blocks/todo/todo_markdown_node.py +0 -21
  307. notionary/blocks/todo/todo_models.py +0 -18
  308. notionary/blocks/toggle/__init__.py +0 -12
  309. notionary/blocks/toggle/toggle_element.py +0 -112
  310. notionary/blocks/toggle/toggle_markdown_node.py +0 -31
  311. notionary/blocks/toggle/toggle_models.py +0 -17
  312. notionary/blocks/toggleable_heading/__init__.py +0 -11
  313. notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
  314. notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
  315. notionary/blocks/types.py +0 -130
  316. notionary/blocks/video/__init__.py +0 -11
  317. notionary/blocks/video/video_element.py +0 -187
  318. notionary/blocks/video/video_element_models.py +0 -10
  319. notionary/blocks/video/video_markdown_node.py +0 -26
  320. notionary/comments/__init__.py +0 -26
  321. notionary/database/__init__.py +0 -4
  322. notionary/database/database.py +0 -480
  323. notionary/database/database_filter_builder.py +0 -173
  324. notionary/database/database_provider.py +0 -227
  325. notionary/database/exceptions.py +0 -13
  326. notionary/database/factory.py +0 -0
  327. notionary/database/models.py +0 -337
  328. notionary/database/notion_database.py +0 -487
  329. notionary/file_upload/__init__.py +0 -7
  330. notionary/page/client.py +0 -124
  331. notionary/page/markdown_whitespace_processor.py +0 -129
  332. notionary/page/models.py +0 -322
  333. notionary/page/notion_page.py +0 -674
  334. notionary/page/page_content_deleting_service.py +0 -117
  335. notionary/page/page_content_writer.py +0 -80
  336. notionary/page/property_formatter.py +0 -99
  337. notionary/page/reader/handler/__init__.py +0 -19
  338. notionary/page/reader/handler/base_block_renderer.py +0 -44
  339. notionary/page/reader/handler/block_processing_context.py +0 -35
  340. notionary/page/reader/handler/block_rendering_context.py +0 -48
  341. notionary/page/reader/handler/column_list_renderer.py +0 -51
  342. notionary/page/reader/handler/column_renderer.py +0 -60
  343. notionary/page/reader/handler/equation_renderer.py +0 -0
  344. notionary/page/reader/handler/line_renderer.py +0 -73
  345. notionary/page/reader/handler/numbered_list_renderer.py +0 -85
  346. notionary/page/reader/handler/toggle_renderer.py +0 -69
  347. notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
  348. notionary/page/reader/page_content_retriever.py +0 -81
  349. notionary/page/search_filter_builder.py +0 -132
  350. notionary/page/utils.py +0 -60
  351. notionary/page/writer/handler/__init__.py +0 -24
  352. notionary/page/writer/handler/code_handler.py +0 -72
  353. notionary/page/writer/handler/column_handler.py +0 -141
  354. notionary/page/writer/handler/column_list_handler.py +0 -139
  355. notionary/page/writer/handler/equation_handler.py +0 -74
  356. notionary/page/writer/handler/line_handler.py +0 -35
  357. notionary/page/writer/handler/line_processing_context.py +0 -54
  358. notionary/page/writer/handler/regular_line_handler.py +0 -86
  359. notionary/page/writer/handler/table_handler.py +0 -66
  360. notionary/page/writer/handler/toggle_handler.py +0 -159
  361. notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
  362. notionary/page/writer/markdown_to_notion_converter.py +0 -139
  363. notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
  364. notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
  365. notionary/page/writer/notion_text_length_processor.py +0 -150
  366. notionary/schemas/__init__.py +0 -3
  367. notionary/schemas/base.py +0 -73
  368. notionary/shared/__init__.py +0 -3
  369. notionary/shared/name_to_id_resolver.py +0 -203
  370. notionary/telemetry/__init__.py +0 -19
  371. notionary/telemetry/service.py +0 -136
  372. notionary/telemetry/views.py +0 -73
  373. notionary/user/base_notion_user.py +0 -53
  374. notionary/user/models.py +0 -84
  375. notionary/user/notion_bot_user.py +0 -226
  376. notionary/user/notion_user.py +0 -255
  377. notionary/user/notion_user_manager.py +0 -101
  378. notionary/util/__init__.py +0 -15
  379. notionary/util/concurrency_limiter.py +0 -0
  380. notionary/util/factory_decorator.py +0 -0
  381. notionary/util/factory_only.py +0 -37
  382. notionary/util/fuzzy.py +0 -75
  383. notionary/util/page_id_utils.py +0 -27
  384. notionary/util/singleton.py +0 -18
  385. notionary/util/singleton_metaclass.py +0 -22
  386. notionary/workspace.py +0 -105
  387. notionary-0.2.26.dist-info/RECORD +0 -202
@@ -1,525 +0,0 @@
1
- """
2
- Clean Fluent Markdown Builder
3
- ============================
4
-
5
- A direct, chainable builder for all MarkdownNode types without overengineering.
6
- Maps 1:1 to the available blocks with clear, expressive method names.
7
- """
8
-
9
- from __future__ import annotations
10
-
11
- from typing import Callable, Optional, Self
12
-
13
- from notionary.blocks.bookmark import BookmarkMarkdownNode
14
- from notionary.blocks.breadcrumbs import BreadcrumbMarkdownNode
15
- from notionary.blocks.bulleted_list import BulletedListMarkdownNode
16
- from notionary.blocks.callout import CalloutMarkdownNode
17
- from notionary.blocks.code import CodeLanguage, CodeMarkdownNode
18
- from notionary.blocks.column import ColumnListMarkdownNode, ColumnMarkdownNode
19
- from notionary.blocks.divider import DividerMarkdownNode
20
- from notionary.blocks.embed import EmbedMarkdownNode
21
- from notionary.blocks.equation import EquationMarkdownNode
22
- from notionary.blocks.file import FileMarkdownNode
23
- from notionary.blocks.heading import HeadingMarkdownNode
24
- from notionary.blocks.image_block import ImageMarkdownNode
25
- from notionary.blocks.numbered_list import NumberedListMarkdownNode
26
- from notionary.blocks.paragraph import ParagraphMarkdownNode
27
- from notionary.blocks.pdf import PdfMarkdownNode
28
- from notionary.blocks.quote import QuoteMarkdownNode
29
- from notionary.blocks.table import TableMarkdownNode
30
- from notionary.blocks.table_of_contents import TableOfContentsMarkdownNode
31
- from notionary.blocks.todo import TodoMarkdownNode
32
- from notionary.blocks.toggle import ToggleMarkdownNode
33
- from notionary.blocks.toggleable_heading import ToggleableHeadingMarkdownNode
34
- from notionary.blocks.video import VideoMarkdownNode
35
- from notionary.blocks.audio import AudioMarkdownNode
36
-
37
- from notionary.blocks.markdown.markdown_node import MarkdownNode
38
-
39
-
40
- class MarkdownBuilder:
41
- """
42
- Fluent interface builder for creating Notion content with clean, direct methods.
43
-
44
- Focuses on the developer API for programmatic content creation.
45
- Model processing is handled by MarkdownModelProcessor.
46
- """
47
-
48
- def __init__(self) -> None:
49
- """Initialize builder with empty children list."""
50
- self.children: list[MarkdownNode] = []
51
-
52
- def h1(self, text: str) -> Self:
53
- """
54
- Add an H1 heading.
55
-
56
- Args:
57
- text: The heading text content
58
- """
59
- self.children.append(HeadingMarkdownNode(text=text, level=1))
60
- return self
61
-
62
- def h2(self, text: str) -> Self:
63
- """
64
- Add an H2 heading.
65
-
66
- Args:
67
- text: The heading text content
68
- """
69
- self.children.append(HeadingMarkdownNode(text=text, level=2))
70
- return self
71
-
72
- def h3(self, text: str) -> Self:
73
- """
74
- Add an H3 heading.
75
-
76
- Args:
77
- text: The heading text content
78
- """
79
- self.children.append(HeadingMarkdownNode(text=text, level=3))
80
- return self
81
-
82
- def heading(self, text: str, level: int = 2) -> Self:
83
- """
84
- Add a heading with specified level.
85
-
86
- Args:
87
- text: The heading text content
88
- level: Heading level (1-3), defaults to 2
89
- """
90
- self.children.append(HeadingMarkdownNode(text=text, level=level))
91
- return self
92
-
93
- def paragraph(self, text: str) -> Self:
94
- """
95
- Add a paragraph block.
96
-
97
- Args:
98
- text: The paragraph text content
99
- """
100
- self.children.append(ParagraphMarkdownNode(text=text))
101
- return self
102
-
103
- def text(self, content: str) -> Self:
104
- """
105
- Add a text paragraph (alias for paragraph).
106
-
107
- Args:
108
- content: The text content
109
- """
110
- return self.paragraph(content)
111
-
112
- def quote(self, text: str) -> Self:
113
- """
114
- Add a blockquote.
115
-
116
- Args:
117
- text: Quote text content
118
- author: Optional quote author/attribution
119
- """
120
- self.children.append(QuoteMarkdownNode(text=text))
121
- return self
122
-
123
- def divider(self) -> Self:
124
- """Add a horizontal divider."""
125
- self.children.append(DividerMarkdownNode())
126
- return self
127
-
128
- def numbered_list(self, items: list[str]) -> Self:
129
- """
130
- Add a numbered list.
131
-
132
- Args:
133
- items: List of text items for the numbered list
134
- """
135
- self.children.append(NumberedListMarkdownNode(texts=items))
136
- return self
137
-
138
- def bulleted_list(self, items: list[str]) -> Self:
139
- """
140
- Add a bulleted list.
141
-
142
- Args:
143
- items: List of text items for the bulleted list
144
- """
145
- self.children.append(BulletedListMarkdownNode(texts=items))
146
- return self
147
-
148
- def todo(self, text: str, checked: bool = False) -> Self:
149
- """
150
- Add a single todo item.
151
-
152
- Args:
153
- text: The todo item text
154
- checked: Whether the todo item is completed, defaults to False
155
- """
156
- self.children.append(TodoMarkdownNode(text=text, checked=checked))
157
- return self
158
-
159
- def todo_list(
160
- self, items: list[str], completed: Optional[list[bool]] = None
161
- ) -> Self:
162
- """
163
- Add multiple todo items.
164
-
165
- Args:
166
- items: List of todo item texts
167
- completed: List of completion states for each item, defaults to all False
168
- """
169
- if completed is None:
170
- completed = [False] * len(items)
171
-
172
- for i, item in enumerate(items):
173
- is_done = completed[i] if i < len(completed) else False
174
- self.children.append(TodoMarkdownNode(text=item, checked=is_done))
175
- return self
176
-
177
- def callout(self, text: str, emoji: Optional[str] = None) -> Self:
178
- """
179
- Add a callout block.
180
-
181
- Args:
182
- text: The callout text content
183
- emoji: Optional emoji for the callout icon
184
- """
185
- self.children.append(CalloutMarkdownNode(text=text, emoji=emoji))
186
- return self
187
-
188
- def toggle(
189
- self, title: str, builder_func: Callable[["MarkdownBuilder"], "MarkdownBuilder"]
190
- ) -> Self:
191
- """
192
- Add a toggle block with content built using the builder API.
193
-
194
- Args:
195
- title: The toggle title/header text
196
- builder_func: Function that receives a MarkdownBuilder and returns it configured
197
-
198
- Example:
199
- builder.toggle("Advanced Settings", lambda t:
200
- t.h3("Configuration")
201
- .paragraph("Settings description")
202
- .table(["Setting", "Value"], [["Debug", "True"]])
203
- .callout("Important note", "⚠️")
204
- )
205
- """
206
- toggle_builder = MarkdownBuilder()
207
- builder_func(toggle_builder)
208
- self.children.append(
209
- ToggleMarkdownNode(title=title, children=toggle_builder.children)
210
- )
211
- return self
212
-
213
- def toggleable_heading(
214
- self,
215
- text: str,
216
- level: int,
217
- builder_func: Callable[["MarkdownBuilder"], "MarkdownBuilder"],
218
- ) -> Self:
219
- """
220
- Add a toggleable heading with content built using the builder API.
221
-
222
- Args:
223
- text: The heading text content
224
- level: Heading level (1-3)
225
- builder_func: Function that receives a MarkdownBuilder and returns it configured
226
-
227
- Example:
228
- builder.toggleable_heading("Advanced Section", 2, lambda t:
229
- t.paragraph("Introduction to this section")
230
- .numbered_list(["Step 1", "Step 2", "Step 3"])
231
- .code("example_code()", "python")
232
- .table(["Feature", "Status"], [["API", "Ready"]])
233
- )
234
- """
235
- toggle_builder = MarkdownBuilder()
236
- builder_func(toggle_builder)
237
- self.children.append(
238
- ToggleableHeadingMarkdownNode(
239
- text=text, level=level, children=toggle_builder.children
240
- )
241
- )
242
- return self
243
-
244
- def image(
245
- self, url: str, caption: Optional[str] = None, alt: Optional[str] = None
246
- ) -> Self:
247
- """
248
- Add an image.
249
-
250
- Args:
251
- url: Image URL or file path
252
- caption: Optional image caption text
253
- alt: Optional alternative text for accessibility
254
- """
255
- self.children.append(ImageMarkdownNode(url=url, caption=caption, alt=alt))
256
- return self
257
-
258
- def video(self, url: str, caption: Optional[str] = None) -> Self:
259
- """
260
- Add a video.
261
-
262
- Args:
263
- url: Video URL or file path
264
- caption: Optional video caption text
265
- """
266
- self.children.append(VideoMarkdownNode(url=url, caption=caption))
267
- return self
268
-
269
- def audio(self, url: str, caption: Optional[str] = None) -> Self:
270
- """
271
- Add audio content.
272
-
273
- Args:
274
- url: Audio file URL or path
275
- caption: Optional audio caption text
276
- """
277
- self.children.append(AudioMarkdownNode(url=url, caption=caption))
278
- return self
279
-
280
- def file(self, url: str, caption: Optional[str] = None) -> Self:
281
- """
282
- Add a file.
283
-
284
- Args:
285
- url: File URL or path
286
- caption: Optional file caption text
287
- """
288
- self.children.append(FileMarkdownNode(url=url, caption=caption))
289
- return self
290
-
291
- def pdf(self, url: str, caption: Optional[str] = None) -> Self:
292
- """
293
- Add a PDF document.
294
-
295
- Args:
296
- url: PDF URL or file path
297
- caption: Optional PDF caption text
298
- """
299
- self.children.append(PdfMarkdownNode(url=url, caption=caption))
300
- return self
301
-
302
- def bookmark(
303
- self, url: str, title: Optional[str] = None, caption: Optional[str] = None
304
- ) -> Self:
305
- """
306
- Add a bookmark.
307
-
308
- Args:
309
- url: Bookmark URL
310
- title: Optional bookmark title
311
- description: Optional bookmark description text
312
- """
313
- self.children.append(
314
- BookmarkMarkdownNode(url=url, title=title, caption=caption)
315
- )
316
- return self
317
-
318
- def embed(self, url: str, caption: Optional[str] = None) -> Self:
319
- """
320
- Add an embed.
321
-
322
- Args:
323
- url: URL to embed (e.g., YouTube, Twitter, etc.)
324
- caption: Optional embed caption text
325
- """
326
- self.children.append(EmbedMarkdownNode(url=url, caption=caption))
327
- return self
328
-
329
- def code(
330
- self, code: str, language: Optional[str] = None, caption: Optional[str] = None
331
- ) -> Self:
332
- """
333
- Add a code block.
334
-
335
- Args:
336
- code: The source code content
337
- language: Optional programming language for syntax highlighting
338
- caption: Optional code block caption text
339
- """
340
- self.children.append(
341
- CodeMarkdownNode(code=code, language=language, caption=caption)
342
- )
343
- return self
344
-
345
- def mermaid(self, diagram: str, caption: Optional[str] = None) -> Self:
346
- """
347
- Add a Mermaid diagram block.
348
-
349
- Args:
350
- diagram: The Mermaid diagram source code
351
- caption: Optional diagram caption text
352
- """
353
- self.children.append(
354
- CodeMarkdownNode(
355
- code=diagram, language=CodeLanguage.MERMAID.value, caption=caption
356
- )
357
- )
358
- return self
359
-
360
- def table(self, headers: list[str], rows: list[list[str]]) -> Self:
361
- """
362
- Add a table.
363
-
364
- Args:
365
- headers: List of column header texts
366
- rows: List of rows, where each row is a list of cell texts
367
- """
368
- self.children.append(TableMarkdownNode(headers=headers, rows=rows))
369
- return self
370
-
371
- def add_custom(self, node: MarkdownNode) -> Self:
372
- """
373
- Add a custom MarkdownNode.
374
-
375
- Args:
376
- node: A custom MarkdownNode instance
377
- """
378
- self.children.append(node)
379
- return self
380
-
381
- def breadcrumb(self) -> Self:
382
- """Add a breadcrumb navigation block."""
383
- self.children.append(BreadcrumbMarkdownNode())
384
- return self
385
-
386
- def equation(self, expression: str) -> Self:
387
- """
388
- Add a LaTeX equation block.
389
-
390
- Args:
391
- expression: LaTeX mathematical expression
392
-
393
- Example:
394
- builder.equation("E = mc^2")
395
- builder.equation("f(x) = \\sin(x) + \\cos(x)")
396
- builder.equation("x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}")
397
- """
398
- self.children.append(EquationMarkdownNode(expression=expression))
399
- return self
400
-
401
- def table_of_contents(self, color: Optional[str] = None) -> Self:
402
- """
403
- Add a table of contents.
404
-
405
- Args:
406
- color: Optional color for the table of contents (e.g., "blue", "blue_background")
407
- """
408
- self.children.append(TableOfContentsMarkdownNode(color=color))
409
- return self
410
-
411
- def columns(
412
- self,
413
- *builder_funcs: Callable[["MarkdownBuilder"], "MarkdownBuilder"],
414
- width_ratios: Optional[list[float]] = None,
415
- ) -> Self:
416
- """
417
- Add multiple columns in a layout.
418
-
419
- Args:
420
- *builder_funcs: Multiple functions, each building one column
421
- width_ratios: Optional list of width ratios (0.0 to 1.0).
422
- If None, columns have equal width.
423
- Length must match number of builder_funcs.
424
-
425
- Examples:
426
- # Equal width (original API unchanged):
427
- builder.columns(
428
- lambda col: col.h2("Left").paragraph("Left content"),
429
- lambda col: col.h2("Right").paragraph("Right content")
430
- )
431
-
432
- # Custom ratios:
433
- builder.columns(
434
- lambda col: col.h2("Main").paragraph("70% width"),
435
- lambda col: col.h2("Sidebar").paragraph("30% width"),
436
- width_ratios=[0.7, 0.3]
437
- )
438
-
439
- # Three columns with custom ratios:
440
- builder.columns(
441
- lambda col: col.h3("Nav").paragraph("Navigation"),
442
- lambda col: col.h2("Main").paragraph("Main content"),
443
- lambda col: col.h3("Ads").paragraph("Advertisement"),
444
- width_ratios=[0.2, 0.6, 0.2]
445
- )
446
- """
447
- if len(builder_funcs) < 2:
448
- raise ValueError("Column layout requires at least 2 columns")
449
-
450
- if width_ratios is not None:
451
- if len(width_ratios) != len(builder_funcs):
452
- raise ValueError(
453
- f"width_ratios length ({len(width_ratios)}) must match number of columns ({len(builder_funcs)})"
454
- )
455
-
456
- ratio_sum = sum(width_ratios)
457
- if not (0.9 <= ratio_sum <= 1.1): # Allow small floating point errors
458
- raise ValueError(f"width_ratios should sum to 1.0, got {ratio_sum}")
459
-
460
- # Create all columns
461
- columns = []
462
- for i, builder_func in enumerate(builder_funcs):
463
- width_ratio = width_ratios[i] if width_ratios else None
464
-
465
- col_builder = MarkdownBuilder()
466
- builder_func(col_builder)
467
-
468
- column_node = ColumnMarkdownNode(
469
- children=col_builder.children, width_ratio=width_ratio
470
- )
471
- columns.append(column_node)
472
-
473
- self.children.append(ColumnListMarkdownNode(columns=columns))
474
- return self
475
-
476
- def column_with_nodes(
477
- self, *nodes: MarkdownNode, width_ratio: Optional[float] = None
478
- ) -> Self:
479
- """
480
- Add a column with pre-built MarkdownNode objects.
481
-
482
- Args:
483
- *nodes: MarkdownNode objects to include in the column
484
- width_ratio: Optional width ratio (0.0 to 1.0)
485
-
486
- Examples:
487
- # Original API (unchanged):
488
- builder.column_with_nodes(
489
- HeadingMarkdownNode(text="Title", level=2),
490
- ParagraphMarkdownNode(text="Content")
491
- )
492
-
493
- # New API with ratio:
494
- builder.column_with_nodes(
495
- HeadingMarkdownNode(text="Sidebar", level=2),
496
- ParagraphMarkdownNode(text="Narrow content"),
497
- width_ratio=0.25
498
- )
499
- """
500
- from notionary.blocks.column.column_markdown_node import ColumnMarkdownNode
501
-
502
- column_node = ColumnMarkdownNode(children=list(nodes), width_ratio=width_ratio)
503
- self.children.append(column_node)
504
- return self
505
-
506
- def _column(
507
- self, builder_func: Callable[[MarkdownBuilder], MarkdownBuilder]
508
- ) -> ColumnMarkdownNode:
509
- """
510
- Internal helper to create a single column.
511
- Use columns() instead for public API.
512
- """
513
- col_builder = MarkdownBuilder()
514
- builder_func(col_builder)
515
- return ColumnMarkdownNode(children=col_builder.children)
516
-
517
- def space(self) -> Self:
518
- """Add vertical spacing."""
519
- return self.paragraph("")
520
-
521
- def build(self) -> str:
522
- """Build and return the final markdown string."""
523
- return "\n\n".join(
524
- child.to_markdown() for child in self.children if child is not None
525
- )
File without changes
@@ -1,25 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from pydantic import BaseModel
3
-
4
-
5
- class MarkdownNode(BaseModel, ABC):
6
- """
7
- Enhanced base class for all Markdown nodes with Pydantic integration.
8
-
9
- This class serves dual purposes:
10
- 1. Runtime representation for markdown generation
11
- 2. Serializable model for structured output (LLM/API)
12
-
13
- The 'type' field acts as a discriminator for Union types and processing.
14
- """
15
-
16
- @abstractmethod
17
- def to_markdown(self) -> str:
18
- """
19
- Returns the Markdown representation of the block.
20
- Must be implemented by subclasses.
21
- """
22
- pass
23
-
24
- def __str__(self):
25
- return self.to_markdown()
@@ -1,4 +0,0 @@
1
- from .caption_mixin import CaptionMixin
2
- from .caption_markdown_node_mixin import CaptionMarkdownNodeMixin
3
-
4
- __all__ = ["CaptionMixin", "CaptionMarkdownNodeMixin"]
@@ -1,31 +0,0 @@
1
- from typing import Optional
2
-
3
-
4
- class CaptionMarkdownNodeMixin:
5
- """Mixin to add caption functionality to MarkdownNode classes."""
6
-
7
- @classmethod
8
- def append_caption_to_markdown(
9
- cls, base_markdown: str, caption: Optional[str]
10
- ) -> str:
11
- """
12
- Append caption to existing markdown if caption is present.
13
- Returns: base_markdown + "(caption:...)" or just base_markdown
14
- """
15
- if not caption:
16
- return base_markdown
17
- return f"{base_markdown}(caption:{caption})"
18
-
19
- @classmethod
20
- def format_caption_for_markdown(cls, caption: Optional[str]) -> str:
21
- """
22
- Format caption text for markdown output.
23
- Returns: "(caption:...)" or empty string
24
- """
25
- if not caption:
26
- return ""
27
- return f"(caption:{caption})"
28
-
29
- def has_caption(self) -> bool:
30
- """Check if this node has a caption."""
31
- return hasattr(self, "caption") and bool(getattr(self, "caption", None))
@@ -1,92 +0,0 @@
1
- from typing import Optional
2
- import re
3
- from notionary.blocks.rich_text.rich_text_models import RichTextObject
4
- from notionary.blocks.rich_text.text_inline_formatter import TextInlineFormatter
5
-
6
-
7
- class CaptionMixin:
8
- """Mixin to add caption parsing functionality to block elements."""
9
-
10
- # Generic caption pattern - finds caption anywhere in text
11
- CAPTION_PATTERN = re.compile(r"\(caption:([^)]*)\)")
12
-
13
- @classmethod
14
- def extract_caption(cls, text: str) -> Optional[str]:
15
- """
16
- Extract caption text from anywhere in the input text.
17
- Returns only the caption content, preserving parentheses in content.
18
- """
19
- # Look for (caption: followed by content followed by )
20
- # Handle cases where caption content contains parentheses
21
- caption_start = text.find("(caption:")
22
- if caption_start == -1:
23
- return None
24
-
25
- # Find the matching closing parenthesis
26
- # Start after "(caption:"
27
- content_start = caption_start + 9 # len("(caption:")
28
- paren_count = 1
29
- pos = content_start
30
-
31
- while pos < len(text) and paren_count > 0:
32
- if text[pos] == "(":
33
- paren_count += 1
34
- elif text[pos] == ")":
35
- paren_count -= 1
36
- pos += 1
37
-
38
- if paren_count == 0:
39
- # Found matching closing parenthesis
40
- return text[content_start : pos - 1]
41
-
42
- return None
43
-
44
- @classmethod
45
- def remove_caption(cls, text: str) -> str:
46
- """
47
- Remove caption from text and return clean text.
48
- Uses the same balanced parentheses logic as extract_caption.
49
- """
50
- caption_start = text.find("(caption:")
51
- if caption_start == -1:
52
- return text.strip()
53
-
54
- # Find the matching closing parenthesis
55
- content_start = caption_start + 9 # len("(caption:")
56
- paren_count = 1
57
- pos = content_start
58
-
59
- while pos < len(text) and paren_count > 0:
60
- if text[pos] == "(":
61
- paren_count += 1
62
- elif text[pos] == ")":
63
- paren_count -= 1
64
- pos += 1
65
-
66
- if paren_count == 0:
67
- # Remove the entire caption including the outer parentheses
68
- return (text[:caption_start] + text[pos:]).strip()
69
-
70
- # Fallback to regex-based removal if balanced parsing fails
71
- return cls.CAPTION_PATTERN.sub("", text).strip()
72
-
73
- @classmethod
74
- def build_caption_rich_text(cls, caption_text: str) -> list[RichTextObject]:
75
- """Return caption as canonical rich text list (with annotations)."""
76
- if not caption_text:
77
- return []
78
- # IMPORTANT: use the same formatter used elsewhere in the app
79
- return [RichTextObject.for_caption(caption_text)]
80
-
81
- @classmethod
82
- async def format_caption_for_markdown(
83
- cls, caption_list: list[RichTextObject]
84
- ) -> str:
85
- """Convert rich text caption back to markdown format."""
86
- if not caption_list:
87
- return ""
88
- # Preserve markdown formatting (bold, italic, etc.)
89
- caption_text = await TextInlineFormatter.extract_text_with_formatting(
90
- caption_list
91
- )
92
- return f"(caption:{caption_text})" if caption_text else ""
@@ -1,3 +0,0 @@
1
- from .file_upload_mixin import FileUploadMixin
2
-
3
- __all__ = ["FileUploadMixin"]