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,227 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING, Optional
4
-
5
- from notionary.database.client import NotionDatabaseClient
6
- from notionary.database.exceptions import DatabaseNotFoundException
7
- from notionary.database.models import NotionDatabaseResponse
8
- from notionary.util import LoggingMixin, SingletonMetaClass, format_uuid
9
- from notionary.util.fuzzy import find_best_match
10
-
11
- if TYPE_CHECKING:
12
- from notionary import NotionDatabase
13
-
14
-
15
- class NotionDatabaseProvider(LoggingMixin, metaclass=SingletonMetaClass):
16
- """
17
- Provider class for creating and caching Notion database instances.
18
-
19
- Prevents duplicate database creation when working with multiple pages from the same database.
20
- Each Notion page references its parent database to determine selectable properties and options.
21
- By caching database instances, this provider avoids excessive network requests when reading options,
22
- significantly improving performance for repeated property lookups across many pages.
23
- """
24
-
25
- def __init__(self):
26
- self._database_cache: dict[str, NotionDatabase] = {}
27
-
28
- async def get_database_by_id(
29
- self, database_id: str, token: Optional[str] = None, force_refresh: bool = False
30
- ) -> NotionDatabase:
31
- """Get a NotionDatabase by ID with caching."""
32
- cache_key = self._create_id_cache_key(database_id)
33
-
34
- if self._should_use_cache(cache_key, force_refresh):
35
- self.logger.debug(f"Using cached database for ID: {database_id}")
36
- return self._database_cache[cache_key]
37
-
38
- database = await self._create_from_database_id(database_id, token)
39
- self._cache_database(database, token)
40
- return database
41
-
42
- async def get_database_by_name(
43
- self,
44
- database_name: str,
45
- token: Optional[str] = None,
46
- min_similarity: float = 0.6,
47
- force_refresh: bool = False,
48
- ) -> NotionDatabase:
49
- """Get a NotionDatabase by name with caching."""
50
- name_cache_key = self._create_name_cache_key(database_name, token)
51
-
52
- if self._should_use_cache(name_cache_key, force_refresh):
53
- return self._database_cache[name_cache_key]
54
-
55
- database = await self._create_from_database_name(
56
- database_name, token, min_similarity
57
- )
58
-
59
- id_cache_key = self._create_id_cache_key(database.id)
60
- if not force_refresh and id_cache_key in self._database_cache:
61
- self.logger.debug(f"Found existing cached database by ID: {database.id}")
62
- existing_database = self._database_cache[id_cache_key]
63
-
64
- self._database_cache[name_cache_key] = existing_database
65
- return existing_database
66
-
67
- self._cache_database(database, token, database_name)
68
- self.logger.debug(f"Cached database: {database.title} (ID: {database.id})")
69
-
70
- return database
71
-
72
- def invalidate_database_cache(self, database_id: str) -> bool:
73
- """
74
- Simply invalidate (remove) cache entries for a database without reloading.
75
-
76
- Args:
77
- database_id: The database ID to invalidate
78
-
79
- Returns:
80
- True if cache entries were found and removed, False otherwise
81
- """
82
-
83
- id_cache_key = self._create_id_cache_key(database_id)
84
- was_cached = id_cache_key in self._database_cache
85
-
86
- if not was_cached:
87
- self.logger.debug(f"No cache entry found for database ID: {database_id}")
88
- return False
89
-
90
- removed_database = self._database_cache.pop(id_cache_key)
91
- self.logger.debug(f"Invalidated cached database: {removed_database.title}")
92
-
93
- name_keys_to_remove = [
94
- cache_key
95
- for cache_key, cached_db in self._database_cache.items()
96
- if (cache_key.startswith("name:") and cached_db.id == database_id)
97
- ]
98
-
99
- for name_key in name_keys_to_remove:
100
- self._database_cache.pop(name_key)
101
- self.logger.debug(f"Invalidated name-based cache: {name_key}")
102
-
103
- return was_cached
104
-
105
- async def _create_from_database_id(
106
- self, database_id: str, token: Optional[str]
107
- ) -> NotionDatabase:
108
- """Create a NotionDatabase from database ID via API."""
109
- formatted_id = format_uuid(database_id) or database_id
110
-
111
- async with NotionDatabaseClient(token=token) as client:
112
- db_response = await client.get_database(formatted_id)
113
- return self._create_from_response(db_response, token)
114
-
115
- async def _create_from_database_name(
116
- self,
117
- database_name: str,
118
- token: Optional[str] = None,
119
- min_similarity: float = 0.6,
120
- ) -> NotionDatabase:
121
- """Create a NotionDatabase by finding it via name with fuzzy matching."""
122
- async with NotionDatabaseClient(token=token) as client:
123
- search_result = await client.search_databases(database_name, limit=10)
124
-
125
- if not search_result.results:
126
- self.logger.warning("No databases found for name: %s", database_name)
127
- raise DatabaseNotFoundException(database_name)
128
-
129
- best_match = find_best_match(
130
- query=database_name,
131
- items=search_result.results,
132
- text_extractor=lambda db: self._extract_title(db),
133
- min_similarity=min_similarity,
134
- )
135
-
136
- if not best_match:
137
- available_titles = [
138
- self._extract_title(db) for db in search_result.results[:5]
139
- ]
140
- self.logger.warning(
141
- "No sufficiently similar database found for '%s' (min: %.3f). Available: %s",
142
- database_name,
143
- min_similarity,
144
- available_titles,
145
- )
146
- raise DatabaseNotFoundException(database_name)
147
-
148
- database_id = best_match.item.id
149
- db_response = await client.get_database(database_id=database_id)
150
- instance = self._create_from_response(db_response, token)
151
-
152
- self.logger.info(
153
- "Created database: '%s' (ID: %s, similarity: %.3f)",
154
- instance.title,
155
- database_id,
156
- best_match.similarity,
157
- )
158
-
159
- return instance
160
-
161
- def _should_use_cache(self, cache_key: str, force_refresh: bool) -> bool:
162
- """Returns True if the cache should be used for the given cache_key."""
163
- return not force_refresh and cache_key in self._database_cache
164
-
165
- def _cache_database(
166
- self,
167
- database: NotionDatabase,
168
- token: Optional[str],
169
- original_name: Optional[str] = None,
170
- ) -> None:
171
- """Cache a database by both ID and name (if provided)."""
172
- # Always cache by ID
173
- id_cache_key = self._create_id_cache_key(database.id)
174
- self._database_cache[id_cache_key] = database
175
-
176
- if original_name:
177
- name_cache_key = self._create_name_cache_key(original_name, token)
178
- self._database_cache[name_cache_key] = database
179
-
180
- def _create_id_cache_key(self, database_id: str) -> str:
181
- """Create cache key for database ID."""
182
- return f"id:{database_id}"
183
-
184
- def _create_name_cache_key(self, database_name: str, token: Optional[str]) -> str:
185
- """Create cache key for database name."""
186
- token_suffix = f":{hash(token)}" if token else ":default"
187
- return f"name:{database_name.lower().strip()}{token_suffix}"
188
-
189
- def _create_from_response(
190
- self, db_response: NotionDatabaseResponse, token: Optional[str]
191
- ) -> NotionDatabase:
192
- """Create NotionDatabase instance from API response."""
193
- from notionary import NotionDatabase
194
-
195
- title = self._extract_title(db_response)
196
- emoji_icon = self._extract_emoji_icon(db_response)
197
-
198
- instance = NotionDatabase(
199
- id=db_response.id,
200
- title=title,
201
- url=db_response.url,
202
- emoji_icon=emoji_icon,
203
- properties=db_response.properties,
204
- token=token,
205
- )
206
-
207
- self.logger.info(
208
- "Created database manager: '%s' (ID: %s)", title, db_response.id
209
- )
210
-
211
- return instance
212
-
213
- def _extract_title(self, db_response: NotionDatabaseResponse) -> str:
214
- """Extract title from database response."""
215
- if db_response.title and len(db_response.title) > 0:
216
- return db_response.title[0].plain_text
217
- return "Untitled Database"
218
-
219
- def _extract_emoji_icon(self, db_response: NotionDatabaseResponse) -> Optional[str]:
220
- """Extract emoji from database response."""
221
- if not db_response.icon:
222
- return None
223
-
224
- if db_response.icon.type == "emoji":
225
- return db_response.icon.emoji
226
-
227
- return None
@@ -1,13 +0,0 @@
1
- class NotionDatabaseException(Exception):
2
- """Base exception for all Notion database operations."""
3
-
4
- pass
5
-
6
-
7
- class DatabaseNotFoundException(NotionDatabaseException):
8
- """Exception raised when a database is not found."""
9
-
10
- def __init__(self, identifier: str, message: str = None):
11
- self.identifier = identifier
12
- self.message = message or f"Database not found: {identifier}"
13
- super().__init__(self.message)
File without changes
@@ -1,337 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Any, Dict, List, Literal, Optional, Union
3
-
4
- from pydantic import BaseModel, ConfigDict
5
-
6
- from notionary.page.models import Cover, Icon
7
-
8
-
9
- @dataclass
10
- class TextContent:
11
- content: str
12
- link: Optional[str] = None
13
-
14
-
15
- @dataclass
16
- class RichText:
17
- type: str
18
- text: TextContent
19
- plain_text: str
20
- href: Optional[str]
21
-
22
-
23
- @dataclass
24
- class User:
25
- object: str
26
- id: str
27
-
28
-
29
- @dataclass
30
- class Parent:
31
- type: Literal["page_id", "workspace", "block_id", "database_id"]
32
- page_id: Optional[str] = None
33
- block_id: Optional[str] = None
34
- database_id: Optional[str] = None
35
-
36
-
37
- # Rich text types for Pydantic models
38
- class TextContentPydantic(BaseModel):
39
- content: str
40
- link: Optional[Dict[str, str]] = None
41
-
42
-
43
- class Annotations(BaseModel):
44
- bold: bool
45
- italic: bool
46
- strikethrough: bool
47
- underline: bool
48
- code: bool
49
- color: str
50
-
51
-
52
- class RichTextItemPydantic(BaseModel):
53
- type: str # 'text', 'mention', 'equation'
54
- text: Optional[TextContentPydantic] = None
55
- annotations: Annotations
56
- plain_text: str
57
- href: Optional[str] = None
58
-
59
-
60
- # Database property schema types (these are schema definitions, not values)
61
- class StatusOption(BaseModel):
62
- id: str
63
- name: str
64
- color: str
65
- description: Optional[str] = None
66
-
67
-
68
- class StatusGroup(BaseModel):
69
- id: str
70
- name: str
71
- color: str
72
- option_ids: List[str]
73
-
74
-
75
- class StatusPropertySchema(BaseModel):
76
- options: List[StatusOption]
77
- groups: List[StatusGroup]
78
-
79
-
80
- class DatabaseStatusProperty(BaseModel):
81
- id: str
82
- name: str
83
- type: Literal["status"]
84
- status: StatusPropertySchema
85
-
86
-
87
- class RelationPropertySchema(BaseModel):
88
- database_id: str
89
- type: str # "single_property"
90
- single_property: Dict[str, Any]
91
-
92
-
93
- class DatabaseRelationProperty(BaseModel):
94
- id: str
95
- name: str
96
- type: Literal["relation"]
97
- relation: RelationPropertySchema
98
-
99
-
100
- class DatabaseUrlProperty(BaseModel):
101
- id: str
102
- name: str
103
- type: Literal["url"]
104
- url: Dict[str, Any] # Usually empty dict
105
-
106
-
107
- class DatabaseRichTextProperty(BaseModel):
108
- id: str
109
- name: str
110
- type: Literal["rich_text"]
111
- rich_text: Dict[str, Any] # Usually empty dict
112
-
113
-
114
- class MultiSelectOption(BaseModel):
115
- id: str
116
- name: str
117
- color: str
118
- description: Optional[str] = None
119
-
120
-
121
- class MultiSelectPropertySchema(BaseModel):
122
- options: List[MultiSelectOption]
123
-
124
-
125
- class DatabaseMultiSelectProperty(BaseModel):
126
- id: str
127
- name: str
128
- type: Literal["multi_select"]
129
- multi_select: MultiSelectPropertySchema
130
-
131
-
132
- class DatabaseTitleProperty(BaseModel):
133
- id: str
134
- name: str
135
- type: Literal["title"]
136
- title: Dict[str, Any] # Usually empty dict
137
-
138
-
139
- # Generic database property for unknown types
140
- class GenericDatabaseProperty(BaseModel):
141
- id: str
142
- name: str
143
- type: str
144
-
145
- model_config = ConfigDict(extra="allow")
146
-
147
-
148
- # Union of all database property types
149
- DatabaseProperty = Union[
150
- DatabaseStatusProperty,
151
- DatabaseRelationProperty,
152
- DatabaseUrlProperty,
153
- DatabaseRichTextProperty,
154
- DatabaseMultiSelectProperty,
155
- DatabaseTitleProperty,
156
- GenericDatabaseProperty,
157
- ]
158
-
159
-
160
- # Page property value types (these are actual values, not schemas)
161
- class StatusValue(BaseModel):
162
- id: str
163
- name: str
164
- color: str
165
-
166
-
167
- class StatusProperty(BaseModel):
168
- id: str
169
- type: str # 'status'
170
- status: Optional[StatusValue] = None
171
-
172
-
173
- class RelationItem(BaseModel):
174
- id: str
175
-
176
-
177
- class RelationProperty(BaseModel):
178
- id: str
179
- type: str # 'relation'
180
- relation: List[RelationItem]
181
- has_more: bool
182
-
183
-
184
- class UrlProperty(BaseModel):
185
- id: str
186
- type: str # 'url'
187
- url: Optional[str] = None
188
-
189
-
190
- class RichTextProperty(BaseModel):
191
- id: str
192
- type: str # 'rich_text'
193
- rich_text: List[RichTextItemPydantic]
194
-
195
-
196
- class MultiSelectItem(BaseModel):
197
- id: str
198
- name: str
199
- color: str
200
-
201
-
202
- class MultiSelectProperty(BaseModel):
203
- id: str
204
- type: str # 'multi_select'
205
- multi_select: List[MultiSelectItem]
206
-
207
-
208
- class TitleProperty(BaseModel):
209
- id: str
210
- type: str # 'title'
211
- title: List[RichTextItemPydantic]
212
-
213
-
214
- # Cover types
215
- class ExternalCover(BaseModel):
216
- url: str
217
-
218
-
219
- class NotionCover(BaseModel):
220
- type: str # 'external', 'file'
221
- external: Optional[ExternalCover] = None
222
-
223
-
224
- # Parent types for Pydantic
225
- class NotionParent(BaseModel):
226
- type: str # 'database_id', 'page_id', 'workspace'
227
- database_id: Optional[str] = None
228
- page_id: Optional[str] = None
229
-
230
-
231
- # User type for Pydantic
232
- class NotionUser(BaseModel):
233
- object: str # 'user'
234
- id: str
235
-
236
-
237
- # Database object
238
- class NotionDatabaseResponse(BaseModel):
239
- """
240
- Represents the response from the Notion API when retrieving a database.
241
- """
242
-
243
- object: Literal["database"]
244
- id: str
245
- cover: Optional[Any] = None
246
- icon: Optional[Icon] = None
247
- cover: Optional[Cover]
248
- created_time: str
249
- last_edited_time: str
250
- created_by: NotionUser
251
- last_edited_by: NotionUser
252
- title: List[RichTextItemPydantic]
253
- description: List[Any]
254
- is_inline: bool
255
- properties: Dict[
256
- str, Any
257
- ] # Using Any for flexibility with different property schemas
258
- parent: NotionParent
259
- url: str
260
- public_url: Optional[str] = None
261
- archived: bool
262
- in_trash: bool
263
-
264
-
265
- class NotionPageResponse(BaseModel):
266
- object: Literal["page"]
267
- id: str
268
- created_time: str
269
- last_edited_time: str
270
- created_by: NotionUser
271
- last_edited_by: NotionUser
272
- cover: Optional[NotionCover] = None
273
- icon: Optional[Icon] = None
274
- parent: NotionParent
275
- archived: bool
276
- in_trash: bool
277
- properties: Dict[str, Any]
278
- url: str
279
- public_url: Optional[str] = None
280
-
281
-
282
- class NotionQueryResponse(BaseModel):
283
- """
284
- Complete Notion search/query response model that can contain both pages and databases.
285
- """
286
-
287
- object: Literal["list"]
288
- results: List[Union[NotionPageResponse, NotionDatabaseResponse]]
289
- next_cursor: Optional[str] = None
290
- has_more: bool
291
- type: Literal["page_or_database"]
292
- page_or_database: Dict[str, Any]
293
- request_id: str
294
-
295
-
296
- # Specific response type for database queries (pages only)
297
- class NotionQueryDatabaseResponse(BaseModel):
298
- """
299
- Notion database query response model for querying pages within a database.
300
- """
301
-
302
- object: Literal["list"]
303
- results: List[NotionPageResponse]
304
- next_cursor: Optional[str] = None
305
- has_more: bool
306
- type: Literal["page_or_database"]
307
- page_or_database: Dict[str, Any]
308
- request_id: str
309
-
310
-
311
- # Specific response type for search results (can be mixed)
312
- class NotionSearchResponse(BaseModel):
313
- """
314
- Notion search response model that can return both pages and databases.
315
- """
316
-
317
- object: Literal["list"]
318
- results: List[Union[NotionPageResponse, NotionDatabaseResponse]]
319
- next_cursor: Optional[str] = None
320
- has_more: bool
321
- type: Literal["page_or_database"]
322
- page_or_database: Dict[str, Any]
323
- request_id: str
324
-
325
-
326
- class NotionDatabaseSearchResponse(BaseModel):
327
- """
328
- Notion search response model for database-only searches.
329
- """
330
-
331
- object: Literal["list"]
332
- results: List[NotionDatabaseResponse]
333
- next_cursor: Optional[str] = None
334
- has_more: bool
335
- type: Literal["page_or_database"]
336
- page_or_database: Dict[str, Any]
337
- request_id: str