notionary 0.2.27__py3-none-any.whl → 0.3.0__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 (395) hide show
  1. notionary/__init__.py +5 -20
  2. notionary/blocks/__init__.py +4 -4
  3. notionary/blocks/client.py +90 -216
  4. notionary/blocks/enums.py +167 -0
  5. notionary/blocks/rich_text/markdown_rich_text_converter.py +280 -0
  6. notionary/blocks/rich_text/models.py +178 -0
  7. notionary/blocks/rich_text/name_id_resolver/__init__.py +13 -0
  8. notionary/blocks/rich_text/name_id_resolver/data_source.py +32 -0
  9. notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
  10. notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
  11. notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
  12. notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
  13. notionary/blocks/rich_text/rich_text_markdown_converter.py +144 -0
  14. notionary/blocks/rich_text/rich_text_patterns.py +42 -0
  15. notionary/blocks/schemas.py +778 -0
  16. notionary/comments/__init__.py +1 -22
  17. notionary/comments/client.py +52 -187
  18. notionary/comments/factory.py +38 -0
  19. notionary/comments/models.py +5 -127
  20. notionary/comments/schemas.py +240 -0
  21. notionary/comments/service.py +34 -0
  22. notionary/data_source/http/client.py +11 -0
  23. notionary/data_source/http/data_source_instance_client.py +104 -0
  24. notionary/data_source/properties/schemas.py +402 -0
  25. notionary/data_source/query/builder.py +448 -0
  26. notionary/data_source/query/resolver.py +114 -0
  27. notionary/data_source/query/schema.py +302 -0
  28. notionary/data_source/query/validator.py +73 -0
  29. notionary/data_source/schema/registry.py +104 -0
  30. notionary/data_source/schema/service.py +136 -0
  31. notionary/data_source/schemas.py +27 -0
  32. notionary/data_source/service.py +377 -0
  33. notionary/database/client.py +30 -135
  34. notionary/database/database_metadata_update_client.py +19 -0
  35. notionary/database/schemas.py +29 -0
  36. notionary/database/service.py +168 -0
  37. notionary/exceptions/__init__.py +33 -0
  38. notionary/exceptions/api.py +41 -0
  39. notionary/exceptions/base.py +2 -0
  40. notionary/exceptions/block_parsing.py +16 -0
  41. notionary/exceptions/data_source/__init__.py +6 -0
  42. notionary/exceptions/data_source/builder.py +182 -0
  43. notionary/exceptions/data_source/properties.py +34 -0
  44. notionary/exceptions/properties.py +58 -0
  45. notionary/exceptions/search.py +57 -0
  46. notionary/file_upload/client.py +18 -30
  47. notionary/file_upload/models.py +7 -8
  48. notionary/file_upload/{notion_file_upload.py → service.py} +29 -64
  49. notionary/http/client.py +204 -0
  50. notionary/http/models.py +50 -0
  51. notionary/page/blocks/client.py +1 -0
  52. notionary/page/content/factory.py +73 -0
  53. notionary/page/content/markdown/__init__.py +5 -0
  54. notionary/page/content/markdown/builder.py +226 -0
  55. notionary/page/content/markdown/nodes/__init__.py +52 -0
  56. notionary/page/content/markdown/nodes/audio.py +23 -0
  57. notionary/page/content/markdown/nodes/base.py +12 -0
  58. notionary/page/content/markdown/nodes/bookmark.py +25 -0
  59. notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
  60. notionary/page/content/markdown/nodes/bulleted_list.py +41 -0
  61. notionary/page/content/markdown/nodes/callout.py +34 -0
  62. notionary/page/content/markdown/nodes/code.py +28 -0
  63. notionary/page/content/markdown/nodes/columns.py +69 -0
  64. notionary/page/content/markdown/nodes/container.py +64 -0
  65. notionary/page/content/markdown/nodes/divider.py +14 -0
  66. notionary/page/content/markdown/nodes/embed.py +23 -0
  67. notionary/page/content/markdown/nodes/equation.py +19 -0
  68. notionary/page/content/markdown/nodes/file.py +23 -0
  69. notionary/page/content/markdown/nodes/heading.py +36 -0
  70. notionary/page/content/markdown/nodes/image.py +23 -0
  71. notionary/page/content/markdown/nodes/mixins/__init__.py +5 -0
  72. notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
  73. notionary/page/content/markdown/nodes/numbered_list.py +38 -0
  74. notionary/page/content/markdown/nodes/paragraph.py +14 -0
  75. notionary/page/content/markdown/nodes/pdf.py +23 -0
  76. notionary/page/content/markdown/nodes/quote.py +27 -0
  77. notionary/page/content/markdown/nodes/space.py +14 -0
  78. notionary/page/content/markdown/nodes/table.py +45 -0
  79. notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
  80. notionary/page/content/markdown/nodes/todo.py +38 -0
  81. notionary/page/content/markdown/nodes/toggle.py +27 -0
  82. notionary/page/content/markdown/nodes/video.py +23 -0
  83. notionary/page/content/parser/context.py +126 -0
  84. notionary/page/content/parser/factory.py +210 -0
  85. notionary/page/content/parser/parsers/__init__.py +58 -0
  86. notionary/page/content/parser/parsers/audio.py +40 -0
  87. notionary/page/content/parser/parsers/base.py +30 -0
  88. notionary/page/content/parser/parsers/bookmark.py +33 -0
  89. notionary/page/content/parser/parsers/breadcrumb.py +33 -0
  90. notionary/page/content/parser/parsers/bulleted_list.py +85 -0
  91. notionary/page/content/parser/parsers/callout.py +100 -0
  92. notionary/page/content/parser/parsers/caption.py +55 -0
  93. notionary/page/content/parser/parsers/code.py +81 -0
  94. notionary/page/content/parser/parsers/column.py +76 -0
  95. notionary/page/content/parser/parsers/column_list.py +81 -0
  96. notionary/page/content/parser/parsers/divider.py +33 -0
  97. notionary/page/content/parser/parsers/embed.py +33 -0
  98. notionary/page/content/parser/parsers/equation.py +65 -0
  99. notionary/page/content/parser/parsers/file.py +42 -0
  100. notionary/page/content/parser/parsers/heading.py +115 -0
  101. notionary/page/content/parser/parsers/image.py +42 -0
  102. notionary/page/content/parser/parsers/numbered_list.py +89 -0
  103. notionary/page/content/parser/parsers/paragraph.py +37 -0
  104. notionary/page/content/parser/parsers/pdf.py +42 -0
  105. notionary/page/content/parser/parsers/quote.py +125 -0
  106. notionary/page/content/parser/parsers/space.py +41 -0
  107. notionary/page/content/parser/parsers/table.py +144 -0
  108. notionary/page/content/parser/parsers/table_of_contents.py +32 -0
  109. notionary/page/content/parser/parsers/todo.py +96 -0
  110. notionary/page/content/parser/parsers/toggle.py +70 -0
  111. notionary/page/content/parser/parsers/video.py +42 -0
  112. notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
  113. notionary/page/content/parser/post_processing/handlers/rich_text_length.py +95 -0
  114. notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +114 -0
  115. notionary/page/content/parser/post_processing/port.py +9 -0
  116. notionary/page/content/parser/post_processing/service.py +16 -0
  117. notionary/page/content/parser/pre_processsing/handlers/__init__.py +11 -0
  118. notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +130 -0
  119. notionary/page/content/parser/pre_processsing/handlers/indentation.py +84 -0
  120. notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
  121. notionary/page/content/parser/pre_processsing/handlers/whitespace.py +73 -0
  122. notionary/page/content/parser/pre_processsing/service.py +15 -0
  123. notionary/page/content/parser/service.py +78 -0
  124. notionary/page/content/renderer/context.py +51 -0
  125. notionary/page/content/renderer/factory.py +231 -0
  126. notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
  127. notionary/page/content/renderer/post_processing/handlers/numbered_list.py +156 -0
  128. notionary/page/content/renderer/post_processing/port.py +7 -0
  129. notionary/page/content/renderer/post_processing/service.py +15 -0
  130. notionary/page/content/renderer/renderers/__init__.py +55 -0
  131. notionary/page/content/renderer/renderers/audio.py +31 -0
  132. notionary/page/content/renderer/renderers/base.py +31 -0
  133. notionary/page/content/renderer/renderers/bookmark.py +25 -0
  134. notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
  135. notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
  136. notionary/page/content/renderer/renderers/callout.py +50 -0
  137. notionary/page/content/renderer/renderers/captioned_block.py +58 -0
  138. notionary/page/content/renderer/renderers/code.py +34 -0
  139. notionary/page/content/renderer/renderers/column.py +53 -0
  140. notionary/page/content/renderer/renderers/column_list.py +44 -0
  141. notionary/page/content/renderer/renderers/divider.py +22 -0
  142. notionary/page/content/renderer/renderers/embed.py +25 -0
  143. notionary/page/content/renderer/renderers/equation.py +37 -0
  144. notionary/page/content/renderer/renderers/fallback.py +24 -0
  145. notionary/page/content/renderer/renderers/file.py +40 -0
  146. notionary/page/content/renderer/renderers/heading.py +95 -0
  147. notionary/page/content/renderer/renderers/image.py +31 -0
  148. notionary/page/content/renderer/renderers/numbered_list.py +42 -0
  149. notionary/page/content/renderer/renderers/paragraph.py +40 -0
  150. notionary/page/content/renderer/renderers/pdf.py +31 -0
  151. notionary/page/content/renderer/renderers/quote.py +49 -0
  152. notionary/page/content/renderer/renderers/table.py +115 -0
  153. notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
  154. notionary/page/content/renderer/renderers/table_row.py +17 -0
  155. notionary/page/content/renderer/renderers/todo.py +56 -0
  156. notionary/page/content/renderer/renderers/toggle.py +52 -0
  157. notionary/page/content/renderer/renderers/video.py +31 -0
  158. notionary/page/content/renderer/service.py +50 -0
  159. notionary/page/content/service.py +68 -0
  160. notionary/page/content/syntax/__init__.py +4 -0
  161. notionary/page/content/syntax/grammar.py +10 -0
  162. notionary/page/content/syntax/models.py +66 -0
  163. notionary/page/content/syntax/registry.py +393 -0
  164. notionary/page/page_context.py +7 -16
  165. notionary/page/page_http_client.py +15 -0
  166. notionary/page/page_metadata_update_client.py +19 -0
  167. notionary/page/properties/client.py +144 -0
  168. notionary/page/properties/factory.py +26 -0
  169. notionary/page/properties/models.py +308 -0
  170. notionary/page/properties/service.py +261 -0
  171. notionary/page/schemas.py +13 -0
  172. notionary/page/service.py +225 -0
  173. notionary/shared/entity/client.py +29 -0
  174. notionary/shared/entity/dto_parsers.py +53 -0
  175. notionary/shared/entity/entity_metadata_update_client.py +41 -0
  176. notionary/shared/entity/schemas.py +45 -0
  177. notionary/shared/entity/service.py +171 -0
  178. notionary/shared/models/cover.py +20 -0
  179. notionary/shared/models/file.py +21 -0
  180. notionary/shared/models/icon.py +28 -0
  181. notionary/shared/models/parent.py +41 -0
  182. notionary/shared/properties/type.py +30 -0
  183. notionary/shared/typings.py +3 -0
  184. notionary/user/__init__.py +4 -8
  185. notionary/user/base.py +138 -0
  186. notionary/user/bot.py +70 -0
  187. notionary/user/client.py +22 -111
  188. notionary/user/person.py +41 -0
  189. notionary/user/schemas.py +67 -0
  190. notionary/user/service.py +65 -0
  191. notionary/utils/date.py +51 -0
  192. notionary/utils/decorators.py +122 -0
  193. notionary/utils/fuzzy.py +68 -0
  194. notionary/utils/mixins/logging.py +58 -0
  195. notionary/utils/pagination.py +100 -0
  196. notionary/utils/uuid_utils.py +20 -0
  197. notionary/workspace/__init__.py +4 -0
  198. notionary/workspace/client.py +62 -0
  199. notionary/workspace/query/__init__.py +3 -0
  200. notionary/workspace/query/builder.py +60 -0
  201. notionary/workspace/query/models.py +61 -0
  202. notionary/workspace/query/service.py +100 -0
  203. notionary/workspace/schemas.py +21 -0
  204. notionary/workspace/service.py +116 -0
  205. notionary-0.3.0.dist-info/METADATA +201 -0
  206. notionary-0.3.0.dist-info/RECORD +209 -0
  207. {notionary-0.2.27.dist-info → notionary-0.3.0.dist-info}/WHEEL +1 -1
  208. {notionary-0.2.27.dist-info → notionary-0.3.0.dist-info/licenses}/LICENSE +9 -9
  209. notionary/base_notion_client.py +0 -219
  210. notionary/blocks/_bootstrap.py +0 -271
  211. notionary/blocks/audio/__init__.py +0 -11
  212. notionary/blocks/audio/audio_element.py +0 -158
  213. notionary/blocks/audio/audio_markdown_node.py +0 -24
  214. notionary/blocks/audio/audio_models.py +0 -10
  215. notionary/blocks/base_block_element.py +0 -42
  216. notionary/blocks/bookmark/__init__.py +0 -12
  217. notionary/blocks/bookmark/bookmark_element.py +0 -83
  218. notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
  219. notionary/blocks/bookmark/bookmark_models.py +0 -15
  220. notionary/blocks/breadcrumbs/__init__.py +0 -15
  221. notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
  222. notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
  223. notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
  224. notionary/blocks/bulleted_list/__init__.py +0 -15
  225. notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
  226. notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
  227. notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
  228. notionary/blocks/callout/__init__.py +0 -12
  229. notionary/blocks/callout/callout_element.py +0 -99
  230. notionary/blocks/callout/callout_markdown_node.py +0 -19
  231. notionary/blocks/callout/callout_models.py +0 -33
  232. notionary/blocks/child_database/__init__.py +0 -14
  233. notionary/blocks/child_database/child_database_element.py +0 -59
  234. notionary/blocks/child_database/child_database_models.py +0 -12
  235. notionary/blocks/child_page/__init__.py +0 -9
  236. notionary/blocks/child_page/child_page_element.py +0 -94
  237. notionary/blocks/child_page/child_page_models.py +0 -12
  238. notionary/blocks/code/__init__.py +0 -11
  239. notionary/blocks/code/code_element.py +0 -149
  240. notionary/blocks/code/code_markdown_node.py +0 -80
  241. notionary/blocks/code/code_models.py +0 -94
  242. notionary/blocks/column/__init__.py +0 -25
  243. notionary/blocks/column/column_element.py +0 -65
  244. notionary/blocks/column/column_list_element.py +0 -52
  245. notionary/blocks/column/column_list_markdown_node.py +0 -34
  246. notionary/blocks/column/column_markdown_node.py +0 -42
  247. notionary/blocks/column/column_models.py +0 -26
  248. notionary/blocks/divider/__init__.py +0 -12
  249. notionary/blocks/divider/divider_element.py +0 -41
  250. notionary/blocks/divider/divider_markdown_node.py +0 -11
  251. notionary/blocks/divider/divider_models.py +0 -12
  252. notionary/blocks/embed/__init__.py +0 -12
  253. notionary/blocks/embed/embed_element.py +0 -98
  254. notionary/blocks/embed/embed_markdown_node.py +0 -19
  255. notionary/blocks/embed/embed_models.py +0 -14
  256. notionary/blocks/equation/__init__.py +0 -13
  257. notionary/blocks/equation/equation_element.py +0 -133
  258. notionary/blocks/equation/equation_element_markdown_node.py +0 -23
  259. notionary/blocks/equation/equation_models.py +0 -11
  260. notionary/blocks/file/__init__.py +0 -23
  261. notionary/blocks/file/file_element.py +0 -133
  262. notionary/blocks/file/file_element_markdown_node.py +0 -24
  263. notionary/blocks/file/file_element_models.py +0 -39
  264. notionary/blocks/heading/__init__.py +0 -19
  265. notionary/blocks/heading/heading_element.py +0 -112
  266. notionary/blocks/heading/heading_markdown_node.py +0 -16
  267. notionary/blocks/heading/heading_models.py +0 -29
  268. notionary/blocks/image_block/__init__.py +0 -11
  269. notionary/blocks/image_block/image_element.py +0 -130
  270. notionary/blocks/image_block/image_markdown_node.py +0 -25
  271. notionary/blocks/image_block/image_models.py +0 -10
  272. notionary/blocks/markdown/markdown_builder.py +0 -525
  273. notionary/blocks/markdown/markdown_document_model.py +0 -0
  274. notionary/blocks/markdown/markdown_node.py +0 -25
  275. notionary/blocks/mixins/captions/__init__.py +0 -4
  276. notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
  277. notionary/blocks/mixins/captions/caption_mixin.py +0 -92
  278. notionary/blocks/mixins/file_upload/__init__.py +0 -3
  279. notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
  280. notionary/blocks/models.py +0 -174
  281. notionary/blocks/numbered_list/__init__.py +0 -16
  282. notionary/blocks/numbered_list/numbered_list_element.py +0 -65
  283. notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
  284. notionary/blocks/numbered_list/numbered_list_models.py +0 -17
  285. notionary/blocks/paragraph/__init__.py +0 -15
  286. notionary/blocks/paragraph/paragraph_element.py +0 -58
  287. notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
  288. notionary/blocks/paragraph/paragraph_models.py +0 -16
  289. notionary/blocks/pdf/__init__.py +0 -11
  290. notionary/blocks/pdf/pdf_element.py +0 -146
  291. notionary/blocks/pdf/pdf_markdown_node.py +0 -24
  292. notionary/blocks/pdf/pdf_models.py +0 -11
  293. notionary/blocks/quote/__init__.py +0 -14
  294. notionary/blocks/quote/quote_element.py +0 -75
  295. notionary/blocks/quote/quote_markdown_node.py +0 -16
  296. notionary/blocks/quote/quote_models.py +0 -18
  297. notionary/blocks/registry/__init__.py +0 -3
  298. notionary/blocks/registry/block_registry.py +0 -150
  299. notionary/blocks/rich_text/__init__.py +0 -33
  300. notionary/blocks/rich_text/rich_text_models.py +0 -221
  301. notionary/blocks/rich_text/text_inline_formatter.py +0 -456
  302. notionary/blocks/syntax_prompt_builder.py +0 -137
  303. notionary/blocks/table/__init__.py +0 -19
  304. notionary/blocks/table/table_element.py +0 -225
  305. notionary/blocks/table/table_markdown_node.py +0 -42
  306. notionary/blocks/table/table_models.py +0 -28
  307. notionary/blocks/table_of_contents/__init__.py +0 -17
  308. notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
  309. notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
  310. notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
  311. notionary/blocks/todo/__init__.py +0 -12
  312. notionary/blocks/todo/todo_element.py +0 -81
  313. notionary/blocks/todo/todo_markdown_node.py +0 -21
  314. notionary/blocks/todo/todo_models.py +0 -18
  315. notionary/blocks/toggle/__init__.py +0 -12
  316. notionary/blocks/toggle/toggle_element.py +0 -112
  317. notionary/blocks/toggle/toggle_markdown_node.py +0 -31
  318. notionary/blocks/toggle/toggle_models.py +0 -17
  319. notionary/blocks/toggleable_heading/__init__.py +0 -11
  320. notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
  321. notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
  322. notionary/blocks/types.py +0 -130
  323. notionary/blocks/video/__init__.py +0 -11
  324. notionary/blocks/video/video_element.py +0 -187
  325. notionary/blocks/video/video_element_models.py +0 -10
  326. notionary/blocks/video/video_markdown_node.py +0 -26
  327. notionary/database/__init__.py +0 -4
  328. notionary/database/database.py +0 -480
  329. notionary/database/database_filter_builder.py +0 -173
  330. notionary/database/database_provider.py +0 -227
  331. notionary/database/exceptions.py +0 -13
  332. notionary/database/models.py +0 -337
  333. notionary/database/notion_database.py +0 -487
  334. notionary/file_upload/__init__.py +0 -7
  335. notionary/page/client.py +0 -124
  336. notionary/page/markdown_whitespace_processor.py +0 -129
  337. notionary/page/models.py +0 -322
  338. notionary/page/notion_page.py +0 -712
  339. notionary/page/page_content_deleting_service.py +0 -117
  340. notionary/page/page_content_writer.py +0 -80
  341. notionary/page/property_formatter.py +0 -99
  342. notionary/page/reader/handler/__init__.py +0 -19
  343. notionary/page/reader/handler/base_block_renderer.py +0 -44
  344. notionary/page/reader/handler/block_processing_context.py +0 -35
  345. notionary/page/reader/handler/block_rendering_context.py +0 -48
  346. notionary/page/reader/handler/column_list_renderer.py +0 -51
  347. notionary/page/reader/handler/column_renderer.py +0 -60
  348. notionary/page/reader/handler/equation_renderer.py +0 -0
  349. notionary/page/reader/handler/line_renderer.py +0 -73
  350. notionary/page/reader/handler/numbered_list_renderer.py +0 -85
  351. notionary/page/reader/handler/toggle_renderer.py +0 -69
  352. notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
  353. notionary/page/reader/page_content_retriever.py +0 -81
  354. notionary/page/search_filter_builder.py +0 -132
  355. notionary/page/utils.py +0 -60
  356. notionary/page/writer/handler/__init__.py +0 -24
  357. notionary/page/writer/handler/code_handler.py +0 -72
  358. notionary/page/writer/handler/column_handler.py +0 -141
  359. notionary/page/writer/handler/column_list_handler.py +0 -139
  360. notionary/page/writer/handler/equation_handler.py +0 -74
  361. notionary/page/writer/handler/line_handler.py +0 -35
  362. notionary/page/writer/handler/line_processing_context.py +0 -54
  363. notionary/page/writer/handler/regular_line_handler.py +0 -86
  364. notionary/page/writer/handler/table_handler.py +0 -66
  365. notionary/page/writer/handler/toggle_handler.py +0 -159
  366. notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
  367. notionary/page/writer/markdown_to_notion_converter.py +0 -139
  368. notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
  369. notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
  370. notionary/page/writer/notion_text_length_processor.py +0 -150
  371. notionary/schemas/__init__.py +0 -3
  372. notionary/schemas/base.py +0 -73
  373. notionary/shared/__init__.py +0 -3
  374. notionary/shared/name_to_id_resolver.py +0 -203
  375. notionary/telemetry/__init__.py +0 -19
  376. notionary/telemetry/service.py +0 -136
  377. notionary/telemetry/views.py +0 -73
  378. notionary/user/base_notion_user.py +0 -53
  379. notionary/user/models.py +0 -84
  380. notionary/user/notion_bot_user.py +0 -226
  381. notionary/user/notion_user.py +0 -255
  382. notionary/user/notion_user_manager.py +0 -101
  383. notionary/util/__init__.py +0 -15
  384. notionary/util/concurrency_limiter.py +0 -0
  385. notionary/util/factory_decorator.py +0 -0
  386. notionary/util/factory_only.py +0 -37
  387. notionary/util/fuzzy.py +0 -75
  388. notionary/util/logging_mixin.py +0 -59
  389. notionary/util/page_id_utils.py +0 -27
  390. notionary/util/singleton.py +0 -18
  391. notionary/util/singleton_metaclass.py +0 -22
  392. notionary/workspace.py +0 -105
  393. notionary-0.2.27.dist-info/METADATA +0 -270
  394. notionary-0.2.27.dist-info/RECORD +0 -202
  395. /notionary/{database → user}/factory.py +0 -0
@@ -1,12 +0,0 @@
1
- from notionary.blocks.divider.divider_element import DividerElement
2
- from notionary.blocks.divider.divider_markdown_node import (
3
- DividerMarkdownNode,
4
- )
5
- from notionary.blocks.divider.divider_models import CreateDividerBlock, DividerBlock
6
-
7
- __all__ = [
8
- "DividerElement",
9
- "DividerBlock",
10
- "CreateDividerBlock",
11
- "DividerMarkdownNode",
12
- ]
@@ -1,41 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import re
4
- from typing import Optional
5
-
6
- from notionary.blocks.base_block_element import BaseBlockElement
7
- from notionary.blocks.divider.divider_models import CreateDividerBlock, DividerBlock
8
- from notionary.blocks.models import Block, BlockCreateResult
9
- from notionary.blocks.types import BlockType
10
-
11
-
12
- class DividerElement(BaseBlockElement):
13
- """
14
- Handles conversion between Markdown horizontal dividers and Notion divider blocks.
15
-
16
- Markdown divider syntax:
17
- - Three or more hyphens (---) on a line by themselves
18
- """
19
-
20
- PATTERN = re.compile(r"^\s*-{3,}\s*$")
21
-
22
- @classmethod
23
- def match_notion(cls, block: Block) -> bool:
24
- """Check if this element can handle the given Notion block."""
25
- return block.type == BlockType.DIVIDER and block.divider
26
-
27
- @classmethod
28
- async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
29
- """Convert markdown horizontal rule to Notion divider, with preceding empty paragraph."""
30
- if not cls.PATTERN.match(text.strip()):
31
- return None
32
-
33
- divider = DividerBlock()
34
-
35
- return CreateDividerBlock(divider=divider)
36
-
37
- @classmethod
38
- async def notion_to_markdown(cls, block: Block) -> Optional[str]:
39
- if block.type != BlockType.DIVIDER or not block.divider:
40
- return None
41
- return "---"
@@ -1,11 +0,0 @@
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,12 +0,0 @@
1
- from typing import Literal
2
-
3
- from pydantic import BaseModel
4
-
5
-
6
- class DividerBlock(BaseModel):
7
- pass
8
-
9
-
10
- class CreateDividerBlock(BaseModel):
11
- type: Literal["divider"] = "divider"
12
- divider: DividerBlock
@@ -1,12 +0,0 @@
1
- from notionary.blocks.embed.embed_element import EmbedElement
2
- from notionary.blocks.embed.embed_markdown_node import (
3
- EmbedMarkdownNode,
4
- )
5
- from notionary.blocks.embed.embed_models import CreateEmbedBlock, EmbedBlock
6
-
7
- __all__ = [
8
- "EmbedElement",
9
- "EmbedBlock",
10
- "CreateEmbedBlock",
11
- "EmbedMarkdownNode",
12
- ]
@@ -1,98 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import re
4
- from typing import Optional
5
-
6
- from notionary.blocks.base_block_element import BaseBlockElement
7
- from notionary.blocks.embed.embed_models import CreateEmbedBlock, EmbedBlock
8
- from notionary.blocks.file.file_element_models import (
9
- ExternalFile,
10
- FileUploadFile,
11
- NotionHostedFile,
12
- )
13
- from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
14
- from notionary.blocks.models import Block, BlockCreateResult, BlockType
15
- from notionary.blocks.rich_text.rich_text_models import RichTextObject
16
- from notionary.blocks.rich_text.text_inline_formatter import TextInlineFormatter
17
-
18
-
19
- class EmbedElement(BaseBlockElement):
20
- """
21
- Handles conversion between Markdown embeds and Notion embed blocks.
22
-
23
- Markdown embed syntax:
24
- - [embed](https://example.com) - URL only
25
- - [embed](https://example.com "Caption") - URL + caption
26
- """
27
-
28
- PATTERN = re.compile(
29
- r"^\[embed\]\(" # prefix
30
- r"(https?://[^\s\"]+)" # URL
31
- r"(?:\s+\"([^\"]+)\")?" # optional caption
32
- r"\)$"
33
- )
34
-
35
- @classmethod
36
- def match_notion(cls, block: Block) -> bool:
37
- return block.type == BlockType.EMBED and block.embed
38
-
39
- @classmethod
40
- async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
41
- """Convert markdown embed syntax to Notion EmbedBlock."""
42
- match = cls.PATTERN.match(text.strip())
43
- if not match:
44
- return None
45
-
46
- url, rich_text = match.group(1), match.group(2) or ""
47
-
48
- # Build EmbedBlock
49
- embed_block = EmbedBlock(url=url, caption=[])
50
- if rich_text.strip():
51
- rich_text_obj = RichTextObject.from_plain_text(rich_text.strip())
52
- embed_block.caption = [rich_text_obj]
53
-
54
- return CreateEmbedBlock(embed=embed_block)
55
-
56
- @classmethod
57
- async def notion_to_markdown(cls, block: Block) -> Optional[str]:
58
- if block.type != BlockType.EMBED or not block.embed:
59
- return None
60
-
61
- fo = block.embed
62
-
63
- if isinstance(fo, (ExternalFile, NotionHostedFile)):
64
- url = fo.url
65
- elif isinstance(fo, FileUploadFile):
66
- return None
67
- else:
68
- return None
69
-
70
- if not fo.caption:
71
- return f"[embed]({url})"
72
-
73
- text_parts = []
74
- for rt in fo.caption:
75
- if rt.plain_text:
76
- text_parts.append(rt.plain_text)
77
- else:
78
- formatted_text = await TextInlineFormatter.extract_text_with_formatting(
79
- [rt]
80
- )
81
- text_parts.append(formatted_text)
82
- text = "".join(text_parts)
83
-
84
- return f'[embed]({url} "{text}")'
85
-
86
- @classmethod
87
- def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
88
- """Get system prompt information for embed blocks."""
89
- return BlockElementMarkdownInformation(
90
- block_type=cls.__name__,
91
- description="Embed blocks display interactive content from external URLs like videos, maps, or widgets",
92
- syntax_examples=[
93
- "[embed](https://youtube.com/watch?v=123)",
94
- '[embed](https://maps.google.com/location "Map Location")',
95
- '[embed](https://codepen.io/pen/123 "Interactive Demo")',
96
- ],
97
- usage_guidelines="Use for embedding interactive content that supports iframe embedding. URL must be from a supported platform. Caption describes the embedded content.",
98
- )
@@ -1,19 +0,0 @@
1
- from typing import Optional
2
-
3
- from notionary.blocks.markdown.markdown_node import MarkdownNode
4
-
5
-
6
- class EmbedMarkdownNode(MarkdownNode):
7
- """
8
- Enhanced Embed node with Pydantic integration.
9
- Programmatic interface for creating Notion-style Markdown embed blocks.
10
- Example: [embed](https://example.com "Optional caption")
11
- """
12
-
13
- url: str
14
- caption: Optional[str] = None
15
-
16
- def to_markdown(self) -> str:
17
- if self.caption:
18
- return f'[embed]({self.url} "{self.caption}")'
19
- return f"[embed]({self.url})"
@@ -1,14 +0,0 @@
1
- from pydantic import BaseModel, Field
2
- from typing_extensions import Literal
3
-
4
- from notionary.blocks.rich_text.rich_text_models import RichTextObject
5
-
6
-
7
- class EmbedBlock(BaseModel):
8
- url: str
9
- caption: list[RichTextObject] = Field(default_factory=list)
10
-
11
-
12
- class CreateEmbedBlock(BaseModel):
13
- type: Literal["embed"] = "embed"
14
- embed: EmbedBlock
@@ -1,13 +0,0 @@
1
- from notionary.blocks.equation.equation_element import EquationElement
2
- from notionary.blocks.equation.equation_element_markdown_node import (
3
- EquationMarkdownNode,
4
- )
5
- from notionary.blocks.equation.equation_models import CreateEquationBlock, EquationBlock
6
-
7
- __all__ = [
8
- "EquationElement",
9
- "EquationBlock",
10
- "CreateEquationBlock",
11
- "EquationMarkdownNode",
12
- "EquationMarkdownBlockParams",
13
- ]
@@ -1,133 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import re
4
- import textwrap
5
- from typing import Optional
6
-
7
- from notionary.blocks.base_block_element import BaseBlockElement
8
- from notionary.blocks.equation.equation_models import CreateEquationBlock, EquationBlock
9
- from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
10
- from notionary.blocks.models import Block, BlockCreateResult
11
- from notionary.blocks.types import BlockType
12
-
13
-
14
- class EquationElement(BaseBlockElement):
15
- """
16
- Supports standard Markdown equation syntax:
17
-
18
- - $$E = mc^2$$ # simple equations
19
- - $$E = mc^2 + \\frac{a}{b}$$ # complex equations with LaTeX
20
-
21
- Uses $$...$$ parsing for block equations.
22
- """
23
-
24
- _EQUATION_PATTERN = re.compile(
25
- r"^\$\$\s*(?P<expression>.*?)\s*\$\$$",
26
- re.DOTALL,
27
- )
28
-
29
- @classmethod
30
- def match_notion(cls, block: Block) -> bool:
31
- return block.type == BlockType.EQUATION and block.equation
32
-
33
- @classmethod
34
- async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
35
- input_text = text.strip()
36
-
37
- equation_match = cls._EQUATION_PATTERN.match(input_text)
38
- if not equation_match:
39
- return None
40
-
41
- expression = equation_match.group("expression").strip()
42
- if not expression:
43
- return None
44
-
45
- return CreateEquationBlock(equation=EquationBlock(expression=expression))
46
-
47
- @classmethod
48
- def create_from_markdown_block(
49
- cls, opening_line: str, equation_lines: list[str]
50
- ) -> BlockCreateResult:
51
- """
52
- Create a complete equation block from markdown components.
53
- Handles multiline equations like:
54
- $$
55
- some
56
- inline formula here
57
- $$
58
-
59
- Automatically handles:
60
- - Indentation removal from multiline strings
61
- - Single backslash conversion to double backslash for LaTeX line breaks
62
- """
63
- # Check if opening line is just $$
64
- if opening_line.strip() != "$$":
65
- return None
66
-
67
- # Process equation lines if any exist
68
- if equation_lines:
69
- # Remove common indentation from all lines
70
- raw_content = "\n".join(equation_lines)
71
- dedented_content = textwrap.dedent(raw_content)
72
-
73
- # Fix single backslashes at line ends for LaTeX line breaks
74
- fixed_lines = cls._fix_latex_line_breaks(dedented_content.splitlines())
75
- expression = "\n".join(fixed_lines).strip()
76
-
77
- if expression:
78
- return CreateEquationBlock(
79
- equation=EquationBlock(expression=expression)
80
- )
81
-
82
- return None
83
-
84
- @classmethod
85
- def _fix_latex_line_breaks(cls, lines: list[str]) -> list[str]:
86
- """
87
- Fix lines that end with single backslashes by converting them to double backslashes.
88
- This makes LaTeX line breaks work correctly when users write single backslashes.
89
-
90
- Examples:
91
- - "a = b + c \" -> "a = b + c \\"
92
- - "a = b + c \\\\" -> "a = b + c \\\\" (unchanged)
93
- """
94
- fixed_lines = []
95
-
96
- for line in lines:
97
- # Check if line ends with backslashes
98
- backslash_match = re.search(r"(\\+)$", line)
99
- if backslash_match:
100
- backslashes = backslash_match.group(1)
101
- # If odd number of backslashes, the last one needs to be doubled
102
- if len(backslashes) % 2 == 1:
103
- line = line + "\\"
104
-
105
- fixed_lines.append(line)
106
-
107
- return fixed_lines
108
-
109
- @classmethod
110
- async def notion_to_markdown(cls, block: Block) -> Optional[str]:
111
- if block.type != BlockType.EQUATION or not block.equation:
112
- return None
113
-
114
- expression = (block.equation.expression or "").strip()
115
- if not expression:
116
- return None
117
-
118
- return f"$${expression}$$"
119
-
120
- @classmethod
121
- def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
122
- """Get system prompt information for equation blocks."""
123
- return BlockElementMarkdownInformation(
124
- block_type=cls.__name__,
125
- description="Mathematical equations using standard Markdown LaTeX syntax",
126
- syntax_examples=[
127
- "$$E = mc^2$$",
128
- "$$\\frac{a}{b} + \\sqrt{c}$$",
129
- "$$\\int_0^\\infty e^{-x} dx = 1$$",
130
- "$$\\sum_{i=1}^n i = \\frac{n(n+1)}{2}$$",
131
- ],
132
- usage_guidelines="Use for mathematical expressions and formulas. Supports LaTeX syntax. Wrap equations in double dollar signs ($$).",
133
- )
@@ -1,23 +0,0 @@
1
- from notionary.blocks.markdown.markdown_node import MarkdownNode
2
-
3
-
4
- class EquationMarkdownNode(MarkdownNode):
5
- """
6
- Enhanced Equation node with Pydantic integration.
7
- Programmatic interface for creating Markdown equation blocks.
8
- Uses standard Markdown equation syntax with double dollar signs.
9
-
10
- Examples:
11
- $$E = mc^2$$
12
- $$\\frac{a}{b} + \\sqrt{c}$$
13
- $$\\int_0^\\infty e^{-x} dx = 1$$
14
- """
15
-
16
- expression: str
17
-
18
- def to_markdown(self) -> str:
19
- expr = self.expression.strip()
20
- if not expr:
21
- return "$$$$"
22
-
23
- return f"$${expr}$$"
@@ -1,11 +0,0 @@
1
- from pydantic import BaseModel
2
- from typing_extensions import Literal
3
-
4
-
5
- class EquationBlock(BaseModel):
6
- expression: str
7
-
8
-
9
- class CreateEquationBlock(BaseModel):
10
- type: Literal["equation"] = "equation"
11
- equation: EquationBlock
@@ -1,23 +0,0 @@
1
- from notionary.blocks.file.file_element import FileElement
2
- from notionary.blocks.file.file_element_markdown_node import (
3
- FileMarkdownNode,
4
- )
5
- from notionary.blocks.file.file_element_models import (
6
- CreateFileBlock,
7
- ExternalFile,
8
- FileBlock,
9
- FileType,
10
- FileUploadFile,
11
- NotionHostedFile,
12
- )
13
-
14
- __all__ = [
15
- "FileElement",
16
- "FileType",
17
- "ExternalFile",
18
- "NotionHostedFile",
19
- "FileUploadFile",
20
- "FileBlock",
21
- "CreateFileBlock",
22
- "FileMarkdownNode",
23
- ]
@@ -1,133 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import re
4
- from pathlib import Path
5
- from typing import Optional
6
-
7
- from notionary.blocks.base_block_element import BaseBlockElement
8
- from notionary.blocks.file.file_element_models import (
9
- CreateFileBlock,
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
-
20
-
21
- class FileElement(BaseBlockElement, CaptionMixin, FileUploadMixin):
22
- r"""
23
- Handles conversion between Markdown file embeds and Notion file blocks.
24
-
25
- Supports both external URLs and local file uploads.
26
-
27
- Markdown file syntax:
28
- - [file](https://example.com/document.pdf) - External URL
29
- - [file](./local/document.pdf) - Local file (will be uploaded)
30
- - [file](C:\Documents\report.pdf) - Absolute local path (will be uploaded)
31
- - [file](https://example.com/document.pdf)(caption:Annual Report) - With caption
32
- - (caption:Important document)[file](./doc.pdf) - Caption before URL
33
- """
34
-
35
- FILE_PATTERN = re.compile(r"\[file\]\(([^)]+)\)")
36
-
37
- @classmethod
38
- def match_notion(cls, block: Block) -> bool:
39
- return bool(block.type == BlockType.FILE and block.file)
40
-
41
- @classmethod
42
- async def markdown_to_notion(cls, text: str) -> Optional[BlockCreateResult]:
43
- """Convert markdown file link to Notion FileBlock."""
44
- file_path = cls._extract_file_path(text.strip())
45
- if not file_path:
46
- return None
47
-
48
- cls.logger.info(f"Processing file: {file_path}")
49
-
50
- # Extract caption
51
- caption_text = cls.extract_caption(text.strip())
52
- caption_rich_text = cls.build_caption_rich_text(caption_text or "")
53
-
54
- # Determine if it's a local file or external URL
55
- if cls._is_local_file_path(file_path):
56
- cls.logger.debug(f"Detected local file: {file_path}")
57
-
58
- # Upload the local file using mixin method
59
- file_upload_id = await cls._upload_local_file(file_path, "file")
60
- if not file_upload_id:
61
- cls.logger.error(f"Failed to upload file: {file_path}")
62
- return None
63
-
64
- # Create FILE_UPLOAD block
65
- file_block = FileBlock(
66
- type=FileType.FILE_UPLOAD,
67
- file_upload=FileUploadFile(id=file_upload_id),
68
- caption=caption_rich_text,
69
- name=Path(file_path).name,
70
- )
71
-
72
- else:
73
- cls.logger.debug(f"Using external URL: {file_path}")
74
-
75
- file_block = FileBlock(
76
- type=FileType.EXTERNAL,
77
- external=ExternalFile(url=file_path),
78
- caption=caption_rich_text,
79
- )
80
-
81
- return CreateFileBlock(file=file_block)
82
-
83
- @classmethod
84
- async def notion_to_markdown(cls, block: Block) -> Optional[str]:
85
- if block.type != BlockType.FILE or not block.file:
86
- return None
87
-
88
- fb: FileBlock = block.file
89
-
90
- # Determine the source for markdown
91
- if fb.type == FileType.EXTERNAL and fb.external:
92
- source = fb.external.url
93
- elif fb.type == FileType.FILE and fb.file:
94
- source = fb.file.url
95
- else:
96
- return None
97
-
98
- result = f"[file]({source})"
99
-
100
- # Add caption if present
101
- caption_markdown = await cls.format_caption_for_markdown(fb.caption or [])
102
- if caption_markdown:
103
- result += caption_markdown
104
-
105
- return result
106
-
107
- @classmethod
108
- def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
109
- """Get system prompt information for file blocks."""
110
- return BlockElementMarkdownInformation(
111
- block_type=cls.__name__,
112
- description="File blocks embed files from external URLs or upload local files with optional captions",
113
- syntax_examples=[
114
- "[file](https://example.com/document.pdf)",
115
- "[file](./local/document.pdf)",
116
- "[file](C:\\Documents\\report.xlsx)",
117
- "[file](https://example.com/document.pdf)(caption:Annual Report)",
118
- "(caption:Q1 Data)[file](./spreadsheet.xlsx)",
119
- "[file](./manual.docx)(caption:**User** manual)",
120
- ],
121
- usage_guidelines="Use for both external URLs and local files. Local files will be automatically uploaded to Notion. Supports various file formats including PDFs, documents, spreadsheets, images. Caption supports rich text formatting and should describe the file content or purpose.",
122
- )
123
-
124
- @classmethod
125
- def _extract_file_path(cls, text: str) -> Optional[str]:
126
- """Extract file path/URL from text, handling caption patterns."""
127
- clean_text = cls.remove_caption(text)
128
-
129
- match = cls.FILE_PATTERN.search(clean_text)
130
- if match:
131
- return match.group(1).strip()
132
-
133
- return None
@@ -1,24 +0,0 @@
1
- from typing import Optional
2
-
3
- from notionary.blocks.markdown.markdown_node import MarkdownNode
4
- from notionary.blocks.mixins.captions import CaptionMarkdownNodeMixin
5
-
6
-
7
- class FileMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
8
- """
9
- Enhanced File node with Pydantic integration.
10
- Programmatic interface for creating Notion-style Markdown file embeds.
11
- """
12
-
13
- url: str
14
- caption: Optional[str] = None
15
-
16
- def to_markdown(self) -> str:
17
- """Return the Markdown representation.
18
-
19
- Examples:
20
- - [file](https://example.com/document.pdf)
21
- - [file](https://example.com/document.pdf)(caption:User manual)
22
- """
23
- base_markdown = f"[file]({self.url})"
24
- return self.append_caption_to_markdown(base_markdown, self.caption)
@@ -1,39 +0,0 @@
1
- from enum import Enum
2
- from typing import Literal, Optional
3
-
4
- from pydantic import BaseModel, Field
5
-
6
- from notionary.blocks.rich_text.rich_text_models import RichTextObject
7
-
8
-
9
- class FileType(str, Enum):
10
- EXTERNAL = "external"
11
- FILE = "file"
12
- FILE_UPLOAD = "file_upload"
13
-
14
-
15
- class ExternalFile(BaseModel):
16
- url: str
17
-
18
-
19
- class NotionHostedFile(BaseModel):
20
- url: str
21
- expiry_time: str
22
-
23
-
24
- class FileUploadFile(BaseModel):
25
- id: str
26
-
27
-
28
- class FileBlock(BaseModel):
29
- caption: list[RichTextObject] = Field(default_factory=list)
30
- type: FileType
31
- external: Optional[ExternalFile] = None
32
- file: Optional[NotionHostedFile] = None
33
- file_upload: Optional[FileUploadFile] = None
34
- name: Optional[str] = None
35
-
36
-
37
- class CreateFileBlock(BaseModel):
38
- type: Literal["file"] = "file"
39
- file: FileBlock
@@ -1,19 +0,0 @@
1
- from notionary.blocks.heading.heading_element import HeadingElement
2
- from notionary.blocks.heading.heading_markdown_node import (
3
- HeadingMarkdownNode,
4
- )
5
- from notionary.blocks.heading.heading_models import (
6
- CreateHeading1Block,
7
- CreateHeading2Block,
8
- CreateHeading3Block,
9
- HeadingBlock,
10
- )
11
-
12
- __all__ = [
13
- "HeadingElement",
14
- "HeadingBlock",
15
- "CreateHeading1Block",
16
- "CreateHeading2Block",
17
- "CreateHeading3Block",
18
- "HeadingMarkdownNode",
19
- ]