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
@@ -0,0 +1,308 @@
1
+ from enum import StrEnum
2
+ from typing import Annotated, Any, Literal, TypeVar
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+ from notionary.blocks.rich_text.models import RichText
7
+ from notionary.shared.properties.type import PropertyType
8
+ from notionary.shared.typings import JsonDict
9
+ from notionary.user.schemas import PersonUserResponseDto, UserResponseDto
10
+
11
+ # ============================================================================
12
+ # Base Models
13
+ # ============================================================================
14
+
15
+
16
+ class PageProperty(BaseModel):
17
+ id: str
18
+ type: str
19
+
20
+
21
+ class StatusOption(BaseModel):
22
+ id: str
23
+ name: str
24
+
25
+
26
+ class SelectOption(BaseModel):
27
+ id: str | None = None
28
+ name: str
29
+
30
+
31
+ class RelationItem(BaseModel):
32
+ id: str
33
+
34
+
35
+ class DateValue(BaseModel):
36
+ start: str
37
+ end: str | None = None
38
+ time_zone: str | None = None
39
+
40
+
41
+ # ============================================================================
42
+ # File Models
43
+ # ============================================================================
44
+
45
+
46
+ class FileType(StrEnum):
47
+ EXTERNAL = "external"
48
+ FILE = "file"
49
+
50
+
51
+ class ExternalFile(BaseModel):
52
+ """External file hosted outside of Notion."""
53
+
54
+ url: str
55
+
56
+
57
+ class NotionFile(BaseModel):
58
+ """File uploaded to Notion with expiration."""
59
+
60
+ url: str
61
+ expiry_time: str
62
+
63
+
64
+ class FileObject(BaseModel):
65
+ """File object can be external or uploaded to Notion."""
66
+
67
+ name: str
68
+ type: FileType
69
+ external: ExternalFile | None = None
70
+ file: NotionFile | None = None
71
+
72
+
73
+ # ============================================================================
74
+ # Formula Models
75
+ # ============================================================================
76
+
77
+
78
+ class FormulaValueType(StrEnum):
79
+ BOOLEAN = "boolean"
80
+ DATE = "date"
81
+ NUMBER = "number"
82
+ STRING = "string"
83
+
84
+
85
+ class FormulaValue(BaseModel):
86
+ type: FormulaValueType
87
+ boolean: bool | None = None
88
+ date: DateValue | None = None
89
+ number: float | None = None
90
+ string: str | None = None
91
+
92
+
93
+ # ============================================================================
94
+ # Rollup Models
95
+ # ============================================================================
96
+
97
+
98
+ class RollupValueType(StrEnum):
99
+ NUMBER = "number"
100
+ DATE = "date"
101
+ ARRAY = "array"
102
+ INCOMPLETE = "incomplete"
103
+ UNSUPPORTED = "unsupported"
104
+
105
+
106
+ class RollupValue(BaseModel):
107
+ type: RollupValueType
108
+ function: str # e.g., "sum", "count", "average", "max", "min", etc.
109
+ number: float | None = None
110
+ date: DateValue | None = None
111
+ array: list[Any] | None = None
112
+
113
+
114
+ # ============================================================================
115
+ # Unique ID Models
116
+ # ============================================================================
117
+
118
+
119
+ class UniqueIdValue(BaseModel):
120
+ number: int # Auto-incrementing count
121
+ prefix: str | None = None # Optional prefix like "RL"
122
+
123
+
124
+ # ============================================================================
125
+ # Verification Models
126
+ # ============================================================================
127
+
128
+
129
+ class VerificationState(StrEnum):
130
+ VERIFIED = "verified"
131
+ UNVERIFIED = "unverified"
132
+
133
+
134
+ class VerificationValue(BaseModel):
135
+ state: VerificationState
136
+ verified_by: UserResponseDto | None = None
137
+ date: DateValue | None = None # start = verification date, end = expiration
138
+
139
+
140
+ # ============================================================================
141
+ # Page Property Classes
142
+ # ============================================================================
143
+
144
+
145
+ class PageStatusProperty(PageProperty):
146
+ type: Literal[PropertyType.STATUS] = PropertyType.STATUS
147
+ status: StatusOption | None = None
148
+ options: list[StatusOption] = Field(default_factory=list)
149
+
150
+ @property
151
+ def option_names(self) -> list[str]:
152
+ return [option.name for option in self.options]
153
+
154
+
155
+ class PageRelationProperty(PageProperty):
156
+ type: Literal[PropertyType.RELATION] = PropertyType.RELATION
157
+ relation: list[RelationItem] = Field(default_factory=list)
158
+ has_more: bool = False
159
+
160
+
161
+ class PageURLProperty(PageProperty):
162
+ type: Literal[PropertyType.URL] = PropertyType.URL
163
+ url: str | None = None
164
+
165
+
166
+ class PageRichTextProperty(PageProperty):
167
+ type: Literal[PropertyType.RICH_TEXT] = PropertyType.RICH_TEXT
168
+ rich_text: list[RichText] = Field(default_factory=list)
169
+
170
+
171
+ class PageMultiSelectProperty(PageProperty):
172
+ type: Literal[PropertyType.MULTI_SELECT] = PropertyType.MULTI_SELECT
173
+ multi_select: list[SelectOption] = Field(default_factory=list)
174
+ options: list[SelectOption] = Field(default_factory=list)
175
+
176
+ @property
177
+ def option_names(self) -> list[str]:
178
+ return [option.name for option in self.options]
179
+
180
+
181
+ class PageSelectProperty(PageProperty):
182
+ type: Literal[PropertyType.SELECT] = PropertyType.SELECT
183
+ select: SelectOption | None = None
184
+ options: list[SelectOption] = Field(default_factory=list)
185
+
186
+ @property
187
+ def option_names(self) -> list[str]:
188
+ return [option.name for option in self.options]
189
+
190
+
191
+ class PagePeopleProperty(PageProperty):
192
+ type: Literal[PropertyType.PEOPLE] = PropertyType.PEOPLE
193
+ people: list[PersonUserResponseDto] = Field(default_factory=list)
194
+
195
+
196
+ class PageDateProperty(PageProperty):
197
+ type: Literal[PropertyType.DATE] = PropertyType.DATE
198
+ date: DateValue | None = None
199
+
200
+
201
+ class PageTitleProperty(PageProperty):
202
+ type: Literal[PropertyType.TITLE] = PropertyType.TITLE
203
+ title: list[RichText] = Field(default_factory=list)
204
+
205
+
206
+ class PageNumberProperty(PageProperty):
207
+ type: Literal[PropertyType.NUMBER] = PropertyType.NUMBER
208
+ number: float | None = None
209
+
210
+
211
+ class PageCheckboxProperty(PageProperty):
212
+ type: Literal[PropertyType.CHECKBOX] = PropertyType.CHECKBOX
213
+ checkbox: bool = False
214
+
215
+
216
+ class PageEmailProperty(PageProperty):
217
+ type: Literal[PropertyType.EMAIL] = PropertyType.EMAIL
218
+ email: str | None = None
219
+
220
+
221
+ class PagePhoneNumberProperty(PageProperty):
222
+ type: Literal[PropertyType.PHONE_NUMBER] = PropertyType.PHONE_NUMBER
223
+ phone_number: str | None = None
224
+
225
+
226
+ class PageCreatedTimeProperty(PageProperty):
227
+ type: Literal[PropertyType.CREATED_TIME] = PropertyType.CREATED_TIME
228
+ created_time: str # ISO 8601 datetime - read-only
229
+
230
+
231
+ class PageLastEditedTimeProperty(PageProperty):
232
+ type: Literal[PropertyType.LAST_EDITED_TIME] = PropertyType.LAST_EDITED_TIME
233
+ last_edited_time: str # ISO 8601 datetime - read-only
234
+
235
+
236
+ class PageCreatedByProperty(PageProperty):
237
+ type: Literal[PropertyType.CREATED_BY] = PropertyType.CREATED_BY
238
+ created_by: UserResponseDto # User object - read-only
239
+
240
+
241
+ class PageLastEditedByProperty(PageProperty):
242
+ type: Literal[PropertyType.LAST_EDITED_BY] = PropertyType.LAST_EDITED_BY
243
+ last_edited_by: UserResponseDto # User object - read-only
244
+
245
+
246
+ class PageFilesProperty(PageProperty):
247
+ type: Literal[PropertyType.FILES] = PropertyType.FILES
248
+ files: list[FileObject] = Field(default_factory=list)
249
+
250
+
251
+ class PageFormulaProperty(PageProperty):
252
+ type: Literal[PropertyType.FORMULA] = PropertyType.FORMULA
253
+ formula: FormulaValue
254
+
255
+
256
+ class PageRollupProperty(PageProperty):
257
+ type: Literal[PropertyType.ROLLUP] = PropertyType.ROLLUP
258
+ rollup: RollupValue
259
+
260
+
261
+ class PageUniqueIdProperty(PageProperty):
262
+ type: Literal[PropertyType.UNIQUE_ID] = PropertyType.UNIQUE_ID
263
+ unique_id: UniqueIdValue
264
+
265
+
266
+ class PageVerificationProperty(PageProperty):
267
+ type: Literal[PropertyType.VERIFICATION] = PropertyType.VERIFICATION
268
+ verification: VerificationValue
269
+
270
+
271
+ class PageButtonProperty(PageProperty):
272
+ type: Literal[PropertyType.BUTTON] = PropertyType.BUTTON
273
+ button: JsonDict = Field(default_factory=dict)
274
+
275
+
276
+ # ============================================================================
277
+ # Discriminated Union
278
+ # ============================================================================
279
+
280
+
281
+ DiscriminatedPageProperty = Annotated[
282
+ PageStatusProperty
283
+ | PageRelationProperty
284
+ | PageURLProperty
285
+ | PageRichTextProperty
286
+ | PageMultiSelectProperty
287
+ | PageSelectProperty
288
+ | PagePeopleProperty
289
+ | PageDateProperty
290
+ | PageTitleProperty
291
+ | PageNumberProperty
292
+ | PageCheckboxProperty
293
+ | PageEmailProperty
294
+ | PagePhoneNumberProperty
295
+ | PageCreatedTimeProperty
296
+ | PageLastEditedTimeProperty
297
+ | PageCreatedByProperty
298
+ | PageLastEditedByProperty
299
+ | PageFilesProperty
300
+ | PageFormulaProperty
301
+ | PageRollupProperty
302
+ | PageUniqueIdProperty
303
+ | PageVerificationProperty
304
+ | PageButtonProperty,
305
+ Field(discriminator="type"),
306
+ ]
307
+
308
+ PagePropertyT = TypeVar("PagePropertyT", bound=PageProperty)
@@ -0,0 +1,261 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ from typing import TYPE_CHECKING, Never
5
+
6
+ from notionary.blocks.rich_text.rich_text_markdown_converter import convert_rich_text_to_markdown
7
+ from notionary.exceptions.properties import (
8
+ AccessPagePropertyWithoutDataSourceError,
9
+ PagePropertyNotFoundError,
10
+ PagePropertyTypeError,
11
+ )
12
+ from notionary.page.properties.client import PagePropertyHttpClient
13
+ from notionary.page.properties.models import (
14
+ PageCheckboxProperty,
15
+ PageCreatedTimeProperty,
16
+ PageDateProperty,
17
+ PageEmailProperty,
18
+ PageMultiSelectProperty,
19
+ PageNumberProperty,
20
+ PagePeopleProperty,
21
+ PagePhoneNumberProperty,
22
+ PageProperty,
23
+ PagePropertyT,
24
+ PageRelationProperty,
25
+ PageRichTextProperty,
26
+ PageSelectProperty,
27
+ PageStatusProperty,
28
+ PageTitleProperty,
29
+ PageURLProperty,
30
+ )
31
+ from notionary.shared.models.parent import ParentType
32
+
33
+ if TYPE_CHECKING:
34
+ from notionary import NotionDataSource
35
+
36
+
37
+ class PagePropertyHandler:
38
+ def __init__(
39
+ self,
40
+ properties: dict[str, PageProperty],
41
+ parent_type: ParentType,
42
+ page_url: str,
43
+ page_property_http_client: PagePropertyHttpClient,
44
+ parent_data_source: str,
45
+ ) -> None:
46
+ self._properties = properties
47
+ self._parent_type = parent_type
48
+ self._page_url = page_url
49
+ self._property_http_client = page_property_http_client
50
+ self._parent_data_source_id = parent_data_source
51
+ self._parent_data_source: NotionDataSource | None = None
52
+ self._data_source_loaded = False
53
+
54
+ # =========================================================================
55
+ # Reader Methods
56
+ # =========================================================================
57
+
58
+ def get_value_of_status_property(self, name: str) -> str | None:
59
+ status_property = self._get_typed_property_or_raise(name, PageStatusProperty)
60
+ return status_property.status.name if status_property.status else None
61
+
62
+ def get_value_of_select_property(self, name: str) -> str | None:
63
+ select_property = self._get_typed_property_or_raise(name, PageSelectProperty)
64
+ return select_property.select.name if select_property.select else None
65
+
66
+ async def get_value_of_title_property(self, name: str) -> str:
67
+ title_property = self._get_typed_property_or_raise(name, PageTitleProperty)
68
+ return await convert_rich_text_to_markdown(title_property.title)
69
+
70
+ def get_values_of_people_property(self, property_name: str) -> list[str]:
71
+ people_prop = self._get_typed_property_or_raise(property_name, PagePeopleProperty)
72
+ return [person.name for person in people_prop.people if person.name]
73
+
74
+ def get_value_of_created_time_property(self, name: str) -> str | None:
75
+ created_time_property = self._get_typed_property_or_raise(name, PageCreatedTimeProperty)
76
+ return created_time_property.created_time
77
+
78
+ async def get_values_of_relation_property(self, name: str) -> list[str]:
79
+ from notionary import NotionPage
80
+
81
+ relation_property = self._get_typed_property_or_raise(name, PageRelationProperty)
82
+ relation_page_ids = [rel.id for rel in relation_property.relation]
83
+ notion_pages = [await NotionPage.from_id(page_id) for page_id in relation_page_ids]
84
+ return [page.title for page in notion_pages if page]
85
+
86
+ def get_values_of_multiselect_property(self, name: str) -> list[str]:
87
+ multiselect_property = self._get_typed_property_or_raise(name, PageMultiSelectProperty)
88
+ return [option.name for option in multiselect_property.multi_select]
89
+
90
+ def get_value_of_url_property(self, name: str) -> str | None:
91
+ url_property = self._get_typed_property_or_raise(name, PageURLProperty)
92
+ return url_property.url
93
+
94
+ def get_value_of_number_property(self, name: str) -> float | None:
95
+ number_property = self._get_typed_property_or_raise(name, PageNumberProperty)
96
+ return number_property.number
97
+
98
+ def get_value_of_checkbox_property(self, name: str) -> bool:
99
+ checkbox_property = self._get_typed_property_or_raise(name, PageCheckboxProperty)
100
+ return checkbox_property.checkbox
101
+
102
+ def get_value_of_date_property(self, name: str) -> str | None:
103
+ date_property = self._get_typed_property_or_raise(name, PageDateProperty)
104
+ return date_property.date.start if date_property.date else None
105
+
106
+ async def get_value_of_rich_text_property(self, name: str) -> str:
107
+ rich_text_property = self._get_typed_property_or_raise(name, PageRichTextProperty)
108
+ return await convert_rich_text_to_markdown(rich_text_property.rich_text)
109
+
110
+ def get_value_of_email_property(self, name: str) -> str | None:
111
+ email_property = self._get_typed_property_or_raise(name, PageEmailProperty)
112
+ return email_property.email
113
+
114
+ def get_value_of_phone_number_property(self, name: str) -> str | None:
115
+ phone_property = self._get_typed_property_or_raise(name, PagePhoneNumberProperty)
116
+ return phone_property.phone_number
117
+
118
+ # =========================================================================
119
+ # Options Getters
120
+ # =========================================================================
121
+
122
+ async def get_select_options_by_property_name(self, property_name: str) -> list[str]:
123
+ data_source = await self._get_parent_data_source_or_raise()
124
+ return data_source.get_select_options_by_property_name(property_name)
125
+
126
+ async def get_multi_select_options_by_property_name(self, property_name: str) -> list[str]:
127
+ data_source = await self._get_parent_data_source_or_raise()
128
+ return data_source.get_multi_select_options_by_property_name(property_name)
129
+
130
+ async def get_status_options_by_property_name(self, property_name: str) -> list[str]:
131
+ data_source = await self._get_parent_data_source_or_raise()
132
+ return data_source.get_status_options_by_property_name(property_name)
133
+
134
+ async def get_relation_options_by_property_name(self, property_name: str) -> list[str]:
135
+ data_source = await self._get_parent_data_source_or_raise()
136
+ return await data_source.get_relation_options_by_property_name(property_name)
137
+
138
+ async def get_options_for_property_by_name(self, property_name: str) -> list[str]:
139
+ data_source = await self._get_parent_data_source_or_raise()
140
+ return await data_source.get_options_for_property_by_name(property_name)
141
+
142
+ async def get_schema_description(self, property_name: str) -> str:
143
+ data_source = await self._get_parent_data_source_or_raise()
144
+ return await data_source.get_schema_description(property_name)
145
+
146
+ # =========================================================================
147
+ # Writer Methods
148
+ # =========================================================================
149
+
150
+ async def set_title_property(self, property_name: str, title: str) -> None:
151
+ self._get_typed_property_or_raise(property_name, PageTitleProperty)
152
+ updated_page = await self._property_http_client.patch_title(property_name, title)
153
+ self._properties = updated_page.properties
154
+
155
+ async def set_rich_text_property(self, property_name: str, text: str) -> None:
156
+ self._get_typed_property_or_raise(property_name, PageRichTextProperty)
157
+ updated_page = await self._property_http_client.patch_rich_text_property(property_name, text)
158
+ self._properties = updated_page.properties
159
+
160
+ async def set_url_property(self, property_name: str, url: str) -> None:
161
+ self._get_typed_property_or_raise(property_name, PageURLProperty)
162
+ updated_page = await self._property_http_client.patch_url_property(property_name, url)
163
+ self._properties = updated_page.properties
164
+
165
+ async def set_email_property(self, property_name: str, email: str) -> None:
166
+ self._get_typed_property_or_raise(property_name, PageEmailProperty)
167
+ updated_page = await self._property_http_client.patch_email_property(property_name, email)
168
+ self._properties = updated_page.properties
169
+
170
+ async def set_phone_number_property(self, property_name: str, phone_number: str) -> None:
171
+ self._get_typed_property_or_raise(property_name, PagePhoneNumberProperty)
172
+ updated_page = await self._property_http_client.patch_phone_property(property_name, phone_number)
173
+ self._properties = updated_page.properties
174
+
175
+ async def set_number_property(self, property_name: str, number: int | float) -> None:
176
+ self._get_typed_property_or_raise(property_name, PageNumberProperty)
177
+ updated_page = await self._property_http_client.patch_number_property(property_name, number)
178
+ self._properties = updated_page.properties
179
+
180
+ async def set_checkbox_property(self, property_name: str, checked: bool) -> None:
181
+ self._get_typed_property_or_raise(property_name, PageCheckboxProperty)
182
+ updated_page = await self._property_http_client.patch_checkbox_property(property_name, checked)
183
+ self._properties = updated_page.properties
184
+
185
+ async def set_date_property(self, property_name: str, date_value: str | dict) -> None:
186
+ self._get_typed_property_or_raise(property_name, PageDateProperty)
187
+ updated_page = await self._property_http_client.patch_date_property(property_name, date_value)
188
+ self._properties = updated_page.properties
189
+
190
+ async def set_select_property_by_option_name(self, property_name: str, option_name: str) -> None:
191
+ self._get_typed_property_or_raise(property_name, PageSelectProperty)
192
+ updated_page = await self._property_http_client.patch_select_property(property_name, option_name)
193
+ self._properties = updated_page.properties
194
+
195
+ async def set_multi_select_property_by_option_names(self, property_name: str, option_names: list[str]) -> None:
196
+ self._get_typed_property_or_raise(property_name, PageMultiSelectProperty)
197
+ updated_page = await self._property_http_client.patch_multi_select_property(property_name, option_names)
198
+ self._properties = updated_page.properties
199
+
200
+ async def set_status_property_by_option_name(self, property_name: str, status: str) -> None:
201
+ self._get_typed_property_or_raise(property_name, PageStatusProperty)
202
+ updated_page = await self._property_http_client.patch_status_property(property_name, status)
203
+ self._properties = updated_page.properties
204
+
205
+ async def set_relation_property_by_page_titles(self, property_name: str, page_titles: list[str]) -> None:
206
+ self._get_typed_property_or_raise(property_name, PageRelationProperty)
207
+ relation_ids = await self._convert_page_titles_to_ids(page_titles)
208
+ updated_page = await self._property_http_client.patch_relation_property(property_name, relation_ids)
209
+ self._properties = updated_page.properties
210
+
211
+ async def _ensure_data_source_loaded(self) -> None:
212
+ from notionary import NotionDataSource
213
+
214
+ if self._data_source_loaded:
215
+ return
216
+
217
+ self._parent_data_source = (
218
+ await NotionDataSource.from_id(self._parent_data_source_id) if self._parent_data_source_id else None
219
+ )
220
+ self._data_source_loaded = True
221
+
222
+ async def _get_parent_data_source_or_raise(self) -> NotionDataSource:
223
+ await self._ensure_data_source_loaded()
224
+
225
+ if not self._parent_data_source:
226
+ raise AccessPagePropertyWithoutDataSourceError(self._parent_type)
227
+ return self._parent_data_source
228
+
229
+ def _get_typed_property_or_raise(self, name: str, property_type: type[PagePropertyT]) -> PagePropertyT:
230
+ prop = self._properties.get(name)
231
+
232
+ if prop is None:
233
+ self._handle_prop_not_found(name)
234
+
235
+ if not isinstance(prop, property_type):
236
+ self._handle_incorrect_type(name, type(prop))
237
+
238
+ return prop
239
+
240
+ def _handle_prop_not_found(self, name: str) -> Never:
241
+ raise PagePropertyNotFoundError(
242
+ property_name=name,
243
+ page_url=self._page_url,
244
+ available_properties=list(self._properties.keys()),
245
+ )
246
+
247
+ def _handle_incorrect_type(self, property_name: str, actual_type: type) -> Never:
248
+ raise PagePropertyTypeError(
249
+ property_name=property_name,
250
+ actual_type=actual_type.__name__,
251
+ )
252
+
253
+ async def _convert_page_titles_to_ids(self, page_titles: list[str]) -> list[str]:
254
+ from notionary import NotionPage
255
+
256
+ if not page_titles:
257
+ return []
258
+
259
+ pages = await asyncio.gather(*[NotionPage.from_title(title=title) for title in page_titles])
260
+
261
+ return [page.id for page in pages if page]
@@ -0,0 +1,13 @@
1
+ from pydantic import BaseModel
2
+
3
+ from notionary.page.properties.models import DiscriminatedPageProperty
4
+ from notionary.shared.entity.schemas import EntityResponseDto
5
+
6
+
7
+ class NotionPageDto(EntityResponseDto):
8
+ archived: bool
9
+ properties: dict[str, DiscriminatedPageProperty]
10
+
11
+
12
+ class PgePropertiesUpdateDto(BaseModel):
13
+ properties: dict[str, DiscriminatedPageProperty]