notionary 0.2.27__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (406) hide show
  1. notionary-0.3.0/.gitignore +94 -0
  2. {notionary-0.2.27 → notionary-0.3.0}/LICENSE +9 -9
  3. notionary-0.3.0/PKG-INFO +201 -0
  4. notionary-0.3.0/README.md +186 -0
  5. notionary-0.3.0/notionary/__init__.py +7 -0
  6. notionary-0.3.0/notionary/blocks/__init__.py +5 -0
  7. notionary-0.3.0/notionary/blocks/client.py +130 -0
  8. notionary-0.3.0/notionary/blocks/enums.py +167 -0
  9. notionary-0.3.0/notionary/blocks/rich_text/markdown_rich_text_converter.py +280 -0
  10. notionary-0.3.0/notionary/blocks/rich_text/models.py +178 -0
  11. notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/__init__.py +13 -0
  12. notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/data_source.py +32 -0
  13. notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
  14. notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
  15. notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
  16. notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
  17. notionary-0.3.0/notionary/blocks/rich_text/rich_text_markdown_converter.py +144 -0
  18. notionary-0.3.0/notionary/blocks/rich_text/rich_text_patterns.py +42 -0
  19. notionary-0.3.0/notionary/blocks/schemas.py +778 -0
  20. notionary-0.3.0/notionary/comments/__init__.py +5 -0
  21. notionary-0.3.0/notionary/comments/client.py +76 -0
  22. notionary-0.3.0/notionary/comments/factory.py +38 -0
  23. notionary-0.3.0/notionary/comments/models.py +7 -0
  24. notionary-0.3.0/notionary/comments/schemas.py +240 -0
  25. notionary-0.3.0/notionary/comments/service.py +34 -0
  26. notionary-0.3.0/notionary/data_source/http/client.py +11 -0
  27. notionary-0.3.0/notionary/data_source/http/data_source_instance_client.py +104 -0
  28. notionary-0.3.0/notionary/data_source/properties/schemas.py +402 -0
  29. notionary-0.3.0/notionary/data_source/query/builder.py +448 -0
  30. notionary-0.3.0/notionary/data_source/query/resolver.py +114 -0
  31. notionary-0.3.0/notionary/data_source/query/schema.py +302 -0
  32. notionary-0.3.0/notionary/data_source/query/validator.py +73 -0
  33. notionary-0.3.0/notionary/data_source/schema/registry.py +104 -0
  34. notionary-0.3.0/notionary/data_source/schema/service.py +136 -0
  35. notionary-0.3.0/notionary/data_source/schemas.py +27 -0
  36. notionary-0.3.0/notionary/data_source/service.py +377 -0
  37. notionary-0.3.0/notionary/database/client.py +43 -0
  38. notionary-0.3.0/notionary/database/database_metadata_update_client.py +19 -0
  39. notionary-0.3.0/notionary/database/schemas.py +29 -0
  40. notionary-0.3.0/notionary/database/service.py +168 -0
  41. notionary-0.3.0/notionary/exceptions/__init__.py +33 -0
  42. notionary-0.3.0/notionary/exceptions/api.py +41 -0
  43. notionary-0.3.0/notionary/exceptions/base.py +2 -0
  44. notionary-0.3.0/notionary/exceptions/block_parsing.py +16 -0
  45. notionary-0.3.0/notionary/exceptions/data_source/__init__.py +6 -0
  46. notionary-0.3.0/notionary/exceptions/data_source/builder.py +182 -0
  47. notionary-0.3.0/notionary/exceptions/data_source/properties.py +34 -0
  48. notionary-0.3.0/notionary/exceptions/properties.py +58 -0
  49. notionary-0.3.0/notionary/exceptions/search.py +57 -0
  50. {notionary-0.2.27 → notionary-0.3.0}/notionary/file_upload/client.py +18 -30
  51. {notionary-0.2.27 → notionary-0.3.0}/notionary/file_upload/models.py +7 -8
  52. notionary-0.2.27/notionary/file_upload/notion_file_upload.py → notionary-0.3.0/notionary/file_upload/service.py +29 -64
  53. notionary-0.3.0/notionary/http/client.py +204 -0
  54. notionary-0.3.0/notionary/http/models.py +50 -0
  55. notionary-0.3.0/notionary/page/blocks/client.py +1 -0
  56. notionary-0.3.0/notionary/page/content/factory.py +73 -0
  57. notionary-0.3.0/notionary/page/content/markdown/__init__.py +5 -0
  58. notionary-0.3.0/notionary/page/content/markdown/builder.py +226 -0
  59. notionary-0.3.0/notionary/page/content/markdown/nodes/__init__.py +52 -0
  60. notionary-0.3.0/notionary/page/content/markdown/nodes/audio.py +23 -0
  61. notionary-0.3.0/notionary/page/content/markdown/nodes/base.py +12 -0
  62. notionary-0.3.0/notionary/page/content/markdown/nodes/bookmark.py +25 -0
  63. notionary-0.3.0/notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
  64. notionary-0.3.0/notionary/page/content/markdown/nodes/bulleted_list.py +41 -0
  65. notionary-0.3.0/notionary/page/content/markdown/nodes/callout.py +34 -0
  66. notionary-0.3.0/notionary/page/content/markdown/nodes/code.py +28 -0
  67. notionary-0.3.0/notionary/page/content/markdown/nodes/columns.py +69 -0
  68. notionary-0.3.0/notionary/page/content/markdown/nodes/container.py +64 -0
  69. notionary-0.3.0/notionary/page/content/markdown/nodes/divider.py +14 -0
  70. notionary-0.3.0/notionary/page/content/markdown/nodes/embed.py +23 -0
  71. notionary-0.3.0/notionary/page/content/markdown/nodes/equation.py +19 -0
  72. notionary-0.3.0/notionary/page/content/markdown/nodes/file.py +23 -0
  73. notionary-0.3.0/notionary/page/content/markdown/nodes/heading.py +36 -0
  74. notionary-0.3.0/notionary/page/content/markdown/nodes/image.py +23 -0
  75. notionary-0.3.0/notionary/page/content/markdown/nodes/mixins/__init__.py +5 -0
  76. notionary-0.3.0/notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
  77. notionary-0.3.0/notionary/page/content/markdown/nodes/numbered_list.py +38 -0
  78. notionary-0.3.0/notionary/page/content/markdown/nodes/paragraph.py +14 -0
  79. notionary-0.3.0/notionary/page/content/markdown/nodes/pdf.py +23 -0
  80. notionary-0.3.0/notionary/page/content/markdown/nodes/quote.py +27 -0
  81. notionary-0.3.0/notionary/page/content/markdown/nodes/space.py +14 -0
  82. notionary-0.3.0/notionary/page/content/markdown/nodes/table.py +45 -0
  83. notionary-0.3.0/notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
  84. notionary-0.3.0/notionary/page/content/markdown/nodes/todo.py +38 -0
  85. notionary-0.3.0/notionary/page/content/markdown/nodes/toggle.py +27 -0
  86. notionary-0.3.0/notionary/page/content/markdown/nodes/video.py +23 -0
  87. notionary-0.3.0/notionary/page/content/parser/context.py +126 -0
  88. notionary-0.3.0/notionary/page/content/parser/factory.py +210 -0
  89. notionary-0.3.0/notionary/page/content/parser/parsers/__init__.py +58 -0
  90. notionary-0.3.0/notionary/page/content/parser/parsers/audio.py +40 -0
  91. notionary-0.3.0/notionary/page/content/parser/parsers/base.py +30 -0
  92. notionary-0.3.0/notionary/page/content/parser/parsers/bookmark.py +33 -0
  93. notionary-0.3.0/notionary/page/content/parser/parsers/breadcrumb.py +33 -0
  94. notionary-0.3.0/notionary/page/content/parser/parsers/bulleted_list.py +85 -0
  95. notionary-0.3.0/notionary/page/content/parser/parsers/callout.py +100 -0
  96. notionary-0.3.0/notionary/page/content/parser/parsers/caption.py +55 -0
  97. notionary-0.3.0/notionary/page/content/parser/parsers/code.py +81 -0
  98. notionary-0.3.0/notionary/page/content/parser/parsers/column.py +76 -0
  99. notionary-0.3.0/notionary/page/content/parser/parsers/column_list.py +81 -0
  100. notionary-0.3.0/notionary/page/content/parser/parsers/divider.py +33 -0
  101. notionary-0.3.0/notionary/page/content/parser/parsers/embed.py +33 -0
  102. notionary-0.3.0/notionary/page/content/parser/parsers/equation.py +65 -0
  103. notionary-0.3.0/notionary/page/content/parser/parsers/file.py +42 -0
  104. notionary-0.3.0/notionary/page/content/parser/parsers/heading.py +115 -0
  105. notionary-0.3.0/notionary/page/content/parser/parsers/image.py +42 -0
  106. notionary-0.3.0/notionary/page/content/parser/parsers/numbered_list.py +89 -0
  107. notionary-0.3.0/notionary/page/content/parser/parsers/paragraph.py +37 -0
  108. notionary-0.3.0/notionary/page/content/parser/parsers/pdf.py +42 -0
  109. notionary-0.3.0/notionary/page/content/parser/parsers/quote.py +125 -0
  110. notionary-0.3.0/notionary/page/content/parser/parsers/space.py +41 -0
  111. notionary-0.3.0/notionary/page/content/parser/parsers/table.py +144 -0
  112. notionary-0.3.0/notionary/page/content/parser/parsers/table_of_contents.py +32 -0
  113. notionary-0.3.0/notionary/page/content/parser/parsers/todo.py +96 -0
  114. notionary-0.3.0/notionary/page/content/parser/parsers/toggle.py +70 -0
  115. notionary-0.3.0/notionary/page/content/parser/parsers/video.py +42 -0
  116. notionary-0.3.0/notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
  117. notionary-0.3.0/notionary/page/content/parser/post_processing/handlers/rich_text_length.py +95 -0
  118. notionary-0.3.0/notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +114 -0
  119. notionary-0.3.0/notionary/page/content/parser/post_processing/port.py +9 -0
  120. notionary-0.3.0/notionary/page/content/parser/post_processing/service.py +16 -0
  121. notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/__init__.py +11 -0
  122. notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +130 -0
  123. notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/indentation.py +84 -0
  124. notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
  125. notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/whitespace.py +73 -0
  126. notionary-0.3.0/notionary/page/content/parser/pre_processsing/service.py +15 -0
  127. notionary-0.3.0/notionary/page/content/parser/service.py +78 -0
  128. notionary-0.3.0/notionary/page/content/renderer/context.py +51 -0
  129. notionary-0.3.0/notionary/page/content/renderer/factory.py +231 -0
  130. notionary-0.3.0/notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
  131. notionary-0.3.0/notionary/page/content/renderer/post_processing/handlers/numbered_list.py +156 -0
  132. notionary-0.3.0/notionary/page/content/renderer/post_processing/port.py +7 -0
  133. notionary-0.3.0/notionary/page/content/renderer/post_processing/service.py +15 -0
  134. notionary-0.3.0/notionary/page/content/renderer/renderers/__init__.py +55 -0
  135. notionary-0.3.0/notionary/page/content/renderer/renderers/audio.py +31 -0
  136. notionary-0.3.0/notionary/page/content/renderer/renderers/base.py +31 -0
  137. notionary-0.3.0/notionary/page/content/renderer/renderers/bookmark.py +25 -0
  138. notionary-0.3.0/notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
  139. notionary-0.3.0/notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
  140. notionary-0.3.0/notionary/page/content/renderer/renderers/callout.py +50 -0
  141. notionary-0.3.0/notionary/page/content/renderer/renderers/captioned_block.py +58 -0
  142. notionary-0.3.0/notionary/page/content/renderer/renderers/code.py +34 -0
  143. notionary-0.3.0/notionary/page/content/renderer/renderers/column.py +53 -0
  144. notionary-0.3.0/notionary/page/content/renderer/renderers/column_list.py +44 -0
  145. notionary-0.3.0/notionary/page/content/renderer/renderers/divider.py +22 -0
  146. notionary-0.3.0/notionary/page/content/renderer/renderers/embed.py +25 -0
  147. notionary-0.3.0/notionary/page/content/renderer/renderers/equation.py +37 -0
  148. notionary-0.3.0/notionary/page/content/renderer/renderers/fallback.py +24 -0
  149. notionary-0.3.0/notionary/page/content/renderer/renderers/file.py +40 -0
  150. notionary-0.3.0/notionary/page/content/renderer/renderers/heading.py +95 -0
  151. notionary-0.3.0/notionary/page/content/renderer/renderers/image.py +31 -0
  152. notionary-0.3.0/notionary/page/content/renderer/renderers/numbered_list.py +42 -0
  153. notionary-0.3.0/notionary/page/content/renderer/renderers/paragraph.py +40 -0
  154. notionary-0.3.0/notionary/page/content/renderer/renderers/pdf.py +31 -0
  155. notionary-0.3.0/notionary/page/content/renderer/renderers/quote.py +49 -0
  156. notionary-0.3.0/notionary/page/content/renderer/renderers/table.py +115 -0
  157. notionary-0.3.0/notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
  158. notionary-0.3.0/notionary/page/content/renderer/renderers/table_row.py +17 -0
  159. notionary-0.3.0/notionary/page/content/renderer/renderers/todo.py +56 -0
  160. notionary-0.3.0/notionary/page/content/renderer/renderers/toggle.py +52 -0
  161. notionary-0.3.0/notionary/page/content/renderer/renderers/video.py +31 -0
  162. notionary-0.3.0/notionary/page/content/renderer/service.py +50 -0
  163. notionary-0.3.0/notionary/page/content/service.py +68 -0
  164. notionary-0.3.0/notionary/page/content/syntax/__init__.py +4 -0
  165. notionary-0.3.0/notionary/page/content/syntax/grammar.py +10 -0
  166. notionary-0.3.0/notionary/page/content/syntax/models.py +66 -0
  167. notionary-0.3.0/notionary/page/content/syntax/registry.py +393 -0
  168. {notionary-0.2.27 → notionary-0.3.0}/notionary/page/page_context.py +7 -16
  169. notionary-0.3.0/notionary/page/page_http_client.py +15 -0
  170. notionary-0.3.0/notionary/page/page_metadata_update_client.py +19 -0
  171. notionary-0.3.0/notionary/page/properties/client.py +144 -0
  172. notionary-0.3.0/notionary/page/properties/factory.py +26 -0
  173. notionary-0.3.0/notionary/page/properties/models.py +308 -0
  174. notionary-0.3.0/notionary/page/properties/service.py +261 -0
  175. notionary-0.3.0/notionary/page/schemas.py +13 -0
  176. notionary-0.3.0/notionary/page/service.py +225 -0
  177. notionary-0.3.0/notionary/shared/entity/client.py +29 -0
  178. notionary-0.3.0/notionary/shared/entity/dto_parsers.py +53 -0
  179. notionary-0.3.0/notionary/shared/entity/entity_metadata_update_client.py +41 -0
  180. notionary-0.3.0/notionary/shared/entity/schemas.py +45 -0
  181. notionary-0.3.0/notionary/shared/entity/service.py +171 -0
  182. notionary-0.3.0/notionary/shared/models/cover.py +20 -0
  183. notionary-0.3.0/notionary/shared/models/file.py +21 -0
  184. notionary-0.3.0/notionary/shared/models/icon.py +28 -0
  185. notionary-0.3.0/notionary/shared/models/parent.py +41 -0
  186. notionary-0.3.0/notionary/shared/properties/type.py +30 -0
  187. notionary-0.3.0/notionary/shared/typings.py +3 -0
  188. notionary-0.3.0/notionary/user/__init__.py +7 -0
  189. notionary-0.3.0/notionary/user/base.py +138 -0
  190. notionary-0.3.0/notionary/user/bot.py +70 -0
  191. notionary-0.3.0/notionary/user/client.py +39 -0
  192. notionary-0.3.0/notionary/user/person.py +41 -0
  193. notionary-0.3.0/notionary/user/schemas.py +67 -0
  194. notionary-0.3.0/notionary/user/service.py +65 -0
  195. notionary-0.3.0/notionary/utils/date.py +51 -0
  196. notionary-0.3.0/notionary/utils/decorators.py +122 -0
  197. notionary-0.3.0/notionary/utils/fuzzy.py +68 -0
  198. notionary-0.3.0/notionary/utils/mixins/logging.py +58 -0
  199. notionary-0.3.0/notionary/utils/pagination.py +100 -0
  200. notionary-0.3.0/notionary/utils/uuid_utils.py +20 -0
  201. notionary-0.3.0/notionary/workspace/__init__.py +4 -0
  202. notionary-0.3.0/notionary/workspace/client.py +62 -0
  203. notionary-0.3.0/notionary/workspace/query/__init__.py +3 -0
  204. notionary-0.3.0/notionary/workspace/query/builder.py +60 -0
  205. notionary-0.3.0/notionary/workspace/query/models.py +61 -0
  206. notionary-0.3.0/notionary/workspace/query/service.py +100 -0
  207. notionary-0.3.0/notionary/workspace/schemas.py +21 -0
  208. notionary-0.3.0/notionary/workspace/service.py +116 -0
  209. notionary-0.3.0/pyproject.toml +72 -0
  210. notionary-0.2.27/PKG-INFO +0 -270
  211. notionary-0.2.27/README.md +0 -246
  212. notionary-0.2.27/notionary/__init__.py +0 -22
  213. notionary-0.2.27/notionary/base_notion_client.py +0 -219
  214. notionary-0.2.27/notionary/blocks/__init__.py +0 -5
  215. notionary-0.2.27/notionary/blocks/_bootstrap.py +0 -271
  216. notionary-0.2.27/notionary/blocks/audio/__init__.py +0 -11
  217. notionary-0.2.27/notionary/blocks/audio/audio_element.py +0 -158
  218. notionary-0.2.27/notionary/blocks/audio/audio_markdown_node.py +0 -24
  219. notionary-0.2.27/notionary/blocks/audio/audio_models.py +0 -10
  220. notionary-0.2.27/notionary/blocks/base_block_element.py +0 -42
  221. notionary-0.2.27/notionary/blocks/bookmark/__init__.py +0 -12
  222. notionary-0.2.27/notionary/blocks/bookmark/bookmark_element.py +0 -83
  223. notionary-0.2.27/notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
  224. notionary-0.2.27/notionary/blocks/bookmark/bookmark_models.py +0 -15
  225. notionary-0.2.27/notionary/blocks/breadcrumbs/__init__.py +0 -15
  226. notionary-0.2.27/notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
  227. notionary-0.2.27/notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
  228. notionary-0.2.27/notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
  229. notionary-0.2.27/notionary/blocks/bulleted_list/__init__.py +0 -15
  230. notionary-0.2.27/notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
  231. notionary-0.2.27/notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
  232. notionary-0.2.27/notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
  233. notionary-0.2.27/notionary/blocks/callout/__init__.py +0 -12
  234. notionary-0.2.27/notionary/blocks/callout/callout_element.py +0 -99
  235. notionary-0.2.27/notionary/blocks/callout/callout_markdown_node.py +0 -19
  236. notionary-0.2.27/notionary/blocks/callout/callout_models.py +0 -33
  237. notionary-0.2.27/notionary/blocks/child_database/__init__.py +0 -14
  238. notionary-0.2.27/notionary/blocks/child_database/child_database_element.py +0 -59
  239. notionary-0.2.27/notionary/blocks/child_database/child_database_models.py +0 -12
  240. notionary-0.2.27/notionary/blocks/child_page/__init__.py +0 -9
  241. notionary-0.2.27/notionary/blocks/child_page/child_page_element.py +0 -94
  242. notionary-0.2.27/notionary/blocks/child_page/child_page_models.py +0 -12
  243. notionary-0.2.27/notionary/blocks/client.py +0 -256
  244. notionary-0.2.27/notionary/blocks/code/__init__.py +0 -11
  245. notionary-0.2.27/notionary/blocks/code/code_element.py +0 -149
  246. notionary-0.2.27/notionary/blocks/code/code_markdown_node.py +0 -80
  247. notionary-0.2.27/notionary/blocks/code/code_models.py +0 -94
  248. notionary-0.2.27/notionary/blocks/column/__init__.py +0 -25
  249. notionary-0.2.27/notionary/blocks/column/column_element.py +0 -65
  250. notionary-0.2.27/notionary/blocks/column/column_list_element.py +0 -52
  251. notionary-0.2.27/notionary/blocks/column/column_list_markdown_node.py +0 -34
  252. notionary-0.2.27/notionary/blocks/column/column_markdown_node.py +0 -42
  253. notionary-0.2.27/notionary/blocks/column/column_models.py +0 -26
  254. notionary-0.2.27/notionary/blocks/divider/__init__.py +0 -12
  255. notionary-0.2.27/notionary/blocks/divider/divider_element.py +0 -41
  256. notionary-0.2.27/notionary/blocks/divider/divider_markdown_node.py +0 -11
  257. notionary-0.2.27/notionary/blocks/divider/divider_models.py +0 -12
  258. notionary-0.2.27/notionary/blocks/embed/__init__.py +0 -12
  259. notionary-0.2.27/notionary/blocks/embed/embed_element.py +0 -98
  260. notionary-0.2.27/notionary/blocks/embed/embed_markdown_node.py +0 -19
  261. notionary-0.2.27/notionary/blocks/embed/embed_models.py +0 -14
  262. notionary-0.2.27/notionary/blocks/equation/__init__.py +0 -13
  263. notionary-0.2.27/notionary/blocks/equation/equation_element.py +0 -133
  264. notionary-0.2.27/notionary/blocks/equation/equation_element_markdown_node.py +0 -23
  265. notionary-0.2.27/notionary/blocks/equation/equation_models.py +0 -11
  266. notionary-0.2.27/notionary/blocks/file/__init__.py +0 -23
  267. notionary-0.2.27/notionary/blocks/file/file_element.py +0 -133
  268. notionary-0.2.27/notionary/blocks/file/file_element_markdown_node.py +0 -24
  269. notionary-0.2.27/notionary/blocks/file/file_element_models.py +0 -39
  270. notionary-0.2.27/notionary/blocks/heading/__init__.py +0 -19
  271. notionary-0.2.27/notionary/blocks/heading/heading_element.py +0 -112
  272. notionary-0.2.27/notionary/blocks/heading/heading_markdown_node.py +0 -16
  273. notionary-0.2.27/notionary/blocks/heading/heading_models.py +0 -29
  274. notionary-0.2.27/notionary/blocks/image_block/__init__.py +0 -11
  275. notionary-0.2.27/notionary/blocks/image_block/image_element.py +0 -130
  276. notionary-0.2.27/notionary/blocks/image_block/image_markdown_node.py +0 -25
  277. notionary-0.2.27/notionary/blocks/image_block/image_models.py +0 -10
  278. notionary-0.2.27/notionary/blocks/markdown/markdown_builder.py +0 -525
  279. notionary-0.2.27/notionary/blocks/markdown/markdown_document_model.py +0 -0
  280. notionary-0.2.27/notionary/blocks/markdown/markdown_node.py +0 -25
  281. notionary-0.2.27/notionary/blocks/mixins/captions/__init__.py +0 -4
  282. notionary-0.2.27/notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
  283. notionary-0.2.27/notionary/blocks/mixins/captions/caption_mixin.py +0 -92
  284. notionary-0.2.27/notionary/blocks/mixins/file_upload/__init__.py +0 -3
  285. notionary-0.2.27/notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
  286. notionary-0.2.27/notionary/blocks/models.py +0 -174
  287. notionary-0.2.27/notionary/blocks/numbered_list/__init__.py +0 -16
  288. notionary-0.2.27/notionary/blocks/numbered_list/numbered_list_element.py +0 -65
  289. notionary-0.2.27/notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
  290. notionary-0.2.27/notionary/blocks/numbered_list/numbered_list_models.py +0 -17
  291. notionary-0.2.27/notionary/blocks/paragraph/__init__.py +0 -15
  292. notionary-0.2.27/notionary/blocks/paragraph/paragraph_element.py +0 -58
  293. notionary-0.2.27/notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
  294. notionary-0.2.27/notionary/blocks/paragraph/paragraph_models.py +0 -16
  295. notionary-0.2.27/notionary/blocks/pdf/__init__.py +0 -11
  296. notionary-0.2.27/notionary/blocks/pdf/pdf_element.py +0 -146
  297. notionary-0.2.27/notionary/blocks/pdf/pdf_markdown_node.py +0 -24
  298. notionary-0.2.27/notionary/blocks/pdf/pdf_models.py +0 -11
  299. notionary-0.2.27/notionary/blocks/quote/__init__.py +0 -14
  300. notionary-0.2.27/notionary/blocks/quote/quote_element.py +0 -75
  301. notionary-0.2.27/notionary/blocks/quote/quote_markdown_node.py +0 -16
  302. notionary-0.2.27/notionary/blocks/quote/quote_models.py +0 -18
  303. notionary-0.2.27/notionary/blocks/registry/__init__.py +0 -3
  304. notionary-0.2.27/notionary/blocks/registry/block_registry.py +0 -150
  305. notionary-0.2.27/notionary/blocks/rich_text/__init__.py +0 -33
  306. notionary-0.2.27/notionary/blocks/rich_text/rich_text_models.py +0 -221
  307. notionary-0.2.27/notionary/blocks/rich_text/text_inline_formatter.py +0 -456
  308. notionary-0.2.27/notionary/blocks/syntax_prompt_builder.py +0 -137
  309. notionary-0.2.27/notionary/blocks/table/__init__.py +0 -19
  310. notionary-0.2.27/notionary/blocks/table/table_element.py +0 -225
  311. notionary-0.2.27/notionary/blocks/table/table_markdown_node.py +0 -42
  312. notionary-0.2.27/notionary/blocks/table/table_models.py +0 -28
  313. notionary-0.2.27/notionary/blocks/table_of_contents/__init__.py +0 -17
  314. notionary-0.2.27/notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
  315. notionary-0.2.27/notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
  316. notionary-0.2.27/notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
  317. notionary-0.2.27/notionary/blocks/todo/__init__.py +0 -12
  318. notionary-0.2.27/notionary/blocks/todo/todo_element.py +0 -81
  319. notionary-0.2.27/notionary/blocks/todo/todo_markdown_node.py +0 -21
  320. notionary-0.2.27/notionary/blocks/todo/todo_models.py +0 -18
  321. notionary-0.2.27/notionary/blocks/toggle/__init__.py +0 -12
  322. notionary-0.2.27/notionary/blocks/toggle/toggle_element.py +0 -112
  323. notionary-0.2.27/notionary/blocks/toggle/toggle_markdown_node.py +0 -31
  324. notionary-0.2.27/notionary/blocks/toggle/toggle_models.py +0 -17
  325. notionary-0.2.27/notionary/blocks/toggleable_heading/__init__.py +0 -11
  326. notionary-0.2.27/notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
  327. notionary-0.2.27/notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
  328. notionary-0.2.27/notionary/blocks/types.py +0 -130
  329. notionary-0.2.27/notionary/blocks/video/__init__.py +0 -11
  330. notionary-0.2.27/notionary/blocks/video/video_element.py +0 -187
  331. notionary-0.2.27/notionary/blocks/video/video_element_models.py +0 -10
  332. notionary-0.2.27/notionary/blocks/video/video_markdown_node.py +0 -26
  333. notionary-0.2.27/notionary/comments/__init__.py +0 -26
  334. notionary-0.2.27/notionary/comments/client.py +0 -211
  335. notionary-0.2.27/notionary/comments/models.py +0 -129
  336. notionary-0.2.27/notionary/database/__init__.py +0 -4
  337. notionary-0.2.27/notionary/database/client.py +0 -148
  338. notionary-0.2.27/notionary/database/database.py +0 -480
  339. notionary-0.2.27/notionary/database/database_filter_builder.py +0 -173
  340. notionary-0.2.27/notionary/database/database_provider.py +0 -227
  341. notionary-0.2.27/notionary/database/exceptions.py +0 -13
  342. notionary-0.2.27/notionary/database/models.py +0 -337
  343. notionary-0.2.27/notionary/database/notion_database.py +0 -487
  344. notionary-0.2.27/notionary/file_upload/__init__.py +0 -7
  345. notionary-0.2.27/notionary/page/client.py +0 -124
  346. notionary-0.2.27/notionary/page/markdown_whitespace_processor.py +0 -129
  347. notionary-0.2.27/notionary/page/models.py +0 -322
  348. notionary-0.2.27/notionary/page/notion_page.py +0 -712
  349. notionary-0.2.27/notionary/page/page_content_deleting_service.py +0 -117
  350. notionary-0.2.27/notionary/page/page_content_writer.py +0 -80
  351. notionary-0.2.27/notionary/page/property_formatter.py +0 -99
  352. notionary-0.2.27/notionary/page/reader/handler/__init__.py +0 -19
  353. notionary-0.2.27/notionary/page/reader/handler/base_block_renderer.py +0 -44
  354. notionary-0.2.27/notionary/page/reader/handler/block_processing_context.py +0 -35
  355. notionary-0.2.27/notionary/page/reader/handler/block_rendering_context.py +0 -48
  356. notionary-0.2.27/notionary/page/reader/handler/column_list_renderer.py +0 -51
  357. notionary-0.2.27/notionary/page/reader/handler/column_renderer.py +0 -60
  358. notionary-0.2.27/notionary/page/reader/handler/equation_renderer.py +0 -0
  359. notionary-0.2.27/notionary/page/reader/handler/line_renderer.py +0 -73
  360. notionary-0.2.27/notionary/page/reader/handler/numbered_list_renderer.py +0 -85
  361. notionary-0.2.27/notionary/page/reader/handler/toggle_renderer.py +0 -69
  362. notionary-0.2.27/notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
  363. notionary-0.2.27/notionary/page/reader/page_content_retriever.py +0 -81
  364. notionary-0.2.27/notionary/page/search_filter_builder.py +0 -132
  365. notionary-0.2.27/notionary/page/utils.py +0 -60
  366. notionary-0.2.27/notionary/page/writer/handler/__init__.py +0 -24
  367. notionary-0.2.27/notionary/page/writer/handler/code_handler.py +0 -72
  368. notionary-0.2.27/notionary/page/writer/handler/column_handler.py +0 -141
  369. notionary-0.2.27/notionary/page/writer/handler/column_list_handler.py +0 -139
  370. notionary-0.2.27/notionary/page/writer/handler/equation_handler.py +0 -74
  371. notionary-0.2.27/notionary/page/writer/handler/line_handler.py +0 -35
  372. notionary-0.2.27/notionary/page/writer/handler/line_processing_context.py +0 -54
  373. notionary-0.2.27/notionary/page/writer/handler/regular_line_handler.py +0 -86
  374. notionary-0.2.27/notionary/page/writer/handler/table_handler.py +0 -66
  375. notionary-0.2.27/notionary/page/writer/handler/toggle_handler.py +0 -159
  376. notionary-0.2.27/notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
  377. notionary-0.2.27/notionary/page/writer/markdown_to_notion_converter.py +0 -139
  378. notionary-0.2.27/notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
  379. notionary-0.2.27/notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
  380. notionary-0.2.27/notionary/page/writer/notion_text_length_processor.py +0 -150
  381. notionary-0.2.27/notionary/schemas/__init__.py +0 -3
  382. notionary-0.2.27/notionary/schemas/base.py +0 -73
  383. notionary-0.2.27/notionary/shared/__init__.py +0 -3
  384. notionary-0.2.27/notionary/shared/name_to_id_resolver.py +0 -203
  385. notionary-0.2.27/notionary/telemetry/__init__.py +0 -19
  386. notionary-0.2.27/notionary/telemetry/service.py +0 -136
  387. notionary-0.2.27/notionary/telemetry/views.py +0 -73
  388. notionary-0.2.27/notionary/user/__init__.py +0 -11
  389. notionary-0.2.27/notionary/user/base_notion_user.py +0 -53
  390. notionary-0.2.27/notionary/user/client.py +0 -128
  391. notionary-0.2.27/notionary/user/models.py +0 -84
  392. notionary-0.2.27/notionary/user/notion_bot_user.py +0 -226
  393. notionary-0.2.27/notionary/user/notion_user.py +0 -255
  394. notionary-0.2.27/notionary/user/notion_user_manager.py +0 -101
  395. notionary-0.2.27/notionary/util/__init__.py +0 -15
  396. notionary-0.2.27/notionary/util/concurrency_limiter.py +0 -0
  397. notionary-0.2.27/notionary/util/factory_decorator.py +0 -0
  398. notionary-0.2.27/notionary/util/factory_only.py +0 -37
  399. notionary-0.2.27/notionary/util/fuzzy.py +0 -75
  400. notionary-0.2.27/notionary/util/logging_mixin.py +0 -59
  401. notionary-0.2.27/notionary/util/page_id_utils.py +0 -27
  402. notionary-0.2.27/notionary/util/singleton.py +0 -18
  403. notionary-0.2.27/notionary/util/singleton_metaclass.py +0 -22
  404. notionary-0.2.27/notionary/workspace.py +0 -105
  405. notionary-0.2.27/pyproject.toml +0 -35
  406. {notionary-0.2.27/notionary/database → notionary-0.3.0/notionary/user}/factory.py +0 -0
@@ -0,0 +1,94 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ temp/
7
+
8
+ # Virtual environments
9
+ venv/
10
+ env/
11
+ .venv/
12
+ .env/
13
+
14
+ # Mkdocs
15
+ site/
16
+
17
+ # Distribution / packaging
18
+ build/
19
+ develop-eggs/
20
+ dist/
21
+ downloads/
22
+ eggs/
23
+ .eggs/
24
+ lib/
25
+ lib64/
26
+ parts/
27
+ sdist/
28
+ var/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+
33
+ # PyInstaller
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Jupyter Notebook checkpoints
55
+ .ipynb_checkpoints
56
+
57
+ # pyenv
58
+ .python-version
59
+
60
+ # mypy
61
+ .mypy_cache/
62
+ .dmypy.json
63
+ dmypy.json
64
+
65
+ # Pyre
66
+ .pyre/
67
+
68
+ # Pytype
69
+ .pytype/
70
+
71
+ # Cython debug symbols
72
+ cython_debug/
73
+
74
+ # VS Code
75
+ .vscode/
76
+
77
+ # JetBrains IDEs (PyCharm, etc.)
78
+ .idea/
79
+
80
+ # MacOS
81
+ .DS_Store
82
+
83
+ # Windows
84
+ Thumbs.db
85
+ ehthumbs.db
86
+ desktop.ini
87
+
88
+ # dotenv files
89
+ .env
90
+
91
+ docs/node_modules/
92
+
93
+ .ruff_cache/
94
+ bandit-report.json
@@ -4,18 +4,18 @@ Copyright (c) 2025 Mathis Kristoffer Arends
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
10
  furnished to do so, subject to the following conditions:
11
11
 
12
- The above copyright notice and this permission notice shall be included in
12
+ The above copyright notice and this permission notice shall be included in
13
13
  all copies or substantial portions of the Software.
14
14
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
  THE SOFTWARE.
@@ -0,0 +1,201 @@
1
+ Metadata-Version: 2.4
2
+ Name: notionary
3
+ Version: 0.3.0
4
+ Summary: Python library for programmatic Notion workspace management - databases, pages, and content with advanced Markdown support
5
+ Project-URL: Homepage, https://github.com/mathisarends/notionary
6
+ Author-email: Mathis Arends <mathisarends27@gmail.com>
7
+ License: MIT
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.11
10
+ Requires-Dist: aiofiles<25.0.0,>=24.1.0
11
+ Requires-Dist: httpx>=0.28.0
12
+ Requires-Dist: pydantic>=2.11.4
13
+ Requires-Dist: python-dotenv<2.0.0,>=1.0.1
14
+ Description-Content-Type: text/markdown
15
+
16
+ <picture>
17
+ <source media="(prefers-color-scheme: dark)" srcset="./static/notionary-dark.png">
18
+ <source media="(prefers-color-scheme: light)" srcset="./static/notionary-light.png">
19
+ <img alt="Notionary logo: dark mode shows a white logo, light mode shows a black logo." src="./static/browser-use.png" width="full">
20
+ </picture>
21
+
22
+ <h1 align="center">The Modern Notion API for Python & AI Agents</h1>
23
+
24
+ <div align="center">
25
+
26
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
27
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
28
+ [![Documentation](https://img.shields.io/badge/docs-mathisarends.github.io-blue.svg)](https://mathisarends.github.io/notionary/)
29
+
30
+ **Transform complex Notion API interactions into simple, Pythonic code.**
31
+ Perfect for developers building AI agents, automation workflows, and dynamic content systems.
32
+
33
+ </div>
34
+
35
+ ---
36
+
37
+ ## Why Notionary?
38
+
39
+ - **AI-Native Design** - Built specifically for AI agents with schema-driven markdown syntax
40
+ - **Smart Discovery** - Find pages and databases by name with fuzzy matching—no more hunting for IDs
41
+ - **Extended Markdown** - Rich syntax for toggles, columns, callouts, and media uploads
42
+ - **Async-First** - Modern Python with full async/await support and high performance
43
+ - **Round-Trip** - Read existing content, modify it, and write it back while preserving formatting
44
+ - **Complete Coverage** - Every Notion block type supported with type safety
45
+
46
+ ---
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install notionary
52
+ ```
53
+
54
+ Set up your [Notion integration](https://www.notion.so/profile/integrations) and configure your token:
55
+
56
+ ```bash
57
+ export NOTION_SECRET=your_integration_key
58
+ ```
59
+
60
+ ---
61
+
62
+ ## See It in Action
63
+
64
+ https://github.com/user-attachments/assets/da8b4691-bee4-4b0f-801e-dccacb630398
65
+
66
+ _Create rich database entries with properties, content, and beautiful formatting_
67
+
68
+ ---
69
+
70
+ ## Quick Start
71
+
72
+ ### Find → Create → Update Flow
73
+
74
+ ```python
75
+ from notionary import NotionPage
76
+
77
+ # Find pages by name with fuzzy matching
78
+ page = await NotionPage.from_title("Meeting Notes")
79
+
80
+ # Define rich content with extended markdown
81
+ content = """
82
+ ## Action Items
83
+ - [x] Review proposal
84
+ - [ ] Schedule meeting
85
+
86
+ [callout](Key decision made! "💡")
87
+
88
+ | Task | Owner | Deadline |
89
+ |------|-------|----------|
90
+ | Design Review | Alice | 2024-03-15 |
91
+ | Implementation | Bob | 2024-03-22 |
92
+
93
+ +++ Budget Details
94
+ See attached spreadsheet...
95
+ +++
96
+ """
97
+
98
+ await page.append_markdown(content)
99
+ ```
100
+
101
+ ### Complete Block Support
102
+
103
+ Every Notion block type with extended syntax:
104
+
105
+ | Block Type | Markdown Syntax | Use Case |
106
+ | ------------- | -------------------------------------------- | ---------------------------- |
107
+ | **Toggles** | `+++ Title\nContent\n+++` | Collapsible sections |
108
+ | **Columns** | `::: columns\n::: column\nContent\n:::\n:::` | Side-by-side layouts |
109
+ | **Tables** | Standard markdown tables | Structured data |
110
+ | **Media** | `[video](./file.mp4)(caption:Description)` | Auto-uploading files |
111
+ | **Code** | Standard code fences with captions | Code snippets |
112
+ | **Equations** | `$LaTeX$` | Mathematical expressions |
113
+ | **TOC** | `[toc]` | Auto-generated navigation |
114
+
115
+ ---
116
+
117
+ ## Key Features
118
+
119
+ <table>
120
+ <tr>
121
+ <td width="50%">
122
+
123
+ ### Smart Discovery
124
+
125
+ - Find pages/databases by name
126
+ - Fuzzy matching for approximate searches
127
+ - No more hunting for IDs or URLs
128
+
129
+ ### Extended Markdown
130
+
131
+ - Rich syntax beyond standard markdown
132
+ - Callouts, toggles, columns, media uploads
133
+ - Schema provided for AI agent integration
134
+
135
+ ### Modern Python
136
+
137
+ - Full async/await support
138
+ - Type hints throughout
139
+ - High-performance batch operations
140
+
141
+ </td>
142
+ <td width="50%">
143
+
144
+ ### Round-Trip Editing
145
+
146
+ - Read existing content as markdown
147
+ - Edit and modify preserving formatting
148
+ - Write back to Notion seamlessly
149
+
150
+ ### AI-Ready Architecture
151
+
152
+ - Schema-driven syntax for LLM prompts
153
+ - Perfect for AI content generation
154
+ - Handles complex nested structures
155
+
156
+ ### Complete Coverage
157
+
158
+ - Every Notion block type supported
159
+ - File uploads with automatic handling
160
+ - Database operations and properties
161
+
162
+ </td>
163
+ </tr>
164
+ </table>
165
+
166
+ ---
167
+
168
+ ## Examples & Documentation
169
+
170
+ ### Full Documentation
171
+
172
+ [**mathisarends.github.io/notionary**](https://mathisarends.github.io/notionary/) - Complete API reference, guides, and tutorials
173
+
174
+ ---
175
+
176
+ ## Contributing
177
+
178
+ We welcome contributions from the community! Whether you're:
179
+
180
+ - **Fixing bugs** - Help improve stability and reliability
181
+ - **Adding features** - Extend functionality for new use cases
182
+ - **Improving docs** - Make the library more accessible
183
+ - **Sharing examples** - Show creative applications and patterns
184
+
185
+ Check our [**Contributing Guide**](https://mathisarends.github.io/notionary/contributing/) to get started.
186
+
187
+ ---
188
+
189
+ <div align="center">
190
+
191
+ **Ready to revolutionize your Notion workflows?**
192
+
193
+ [📖 **Read the Docs**](https://mathisarends.github.io/notionary/) • [🚀 **Getting Started**](https://mathisarends.github.io/notionary/get-started/) • [💻 **Browse Examples**](examples/)
194
+
195
+ _Built with ❤️ for Python developers and AI agents_
196
+
197
+ ---
198
+
199
+ **Transform complex Notion API interactions into simple, powerful code.**
200
+
201
+ </div>
@@ -0,0 +1,186 @@
1
+ <picture>
2
+ <source media="(prefers-color-scheme: dark)" srcset="./static/notionary-dark.png">
3
+ <source media="(prefers-color-scheme: light)" srcset="./static/notionary-light.png">
4
+ <img alt="Notionary logo: dark mode shows a white logo, light mode shows a black logo." src="./static/browser-use.png" width="full">
5
+ </picture>
6
+
7
+ <h1 align="center">The Modern Notion API for Python & AI Agents</h1>
8
+
9
+ <div align="center">
10
+
11
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
12
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
13
+ [![Documentation](https://img.shields.io/badge/docs-mathisarends.github.io-blue.svg)](https://mathisarends.github.io/notionary/)
14
+
15
+ **Transform complex Notion API interactions into simple, Pythonic code.**
16
+ Perfect for developers building AI agents, automation workflows, and dynamic content systems.
17
+
18
+ </div>
19
+
20
+ ---
21
+
22
+ ## Why Notionary?
23
+
24
+ - **AI-Native Design** - Built specifically for AI agents with schema-driven markdown syntax
25
+ - **Smart Discovery** - Find pages and databases by name with fuzzy matching—no more hunting for IDs
26
+ - **Extended Markdown** - Rich syntax for toggles, columns, callouts, and media uploads
27
+ - **Async-First** - Modern Python with full async/await support and high performance
28
+ - **Round-Trip** - Read existing content, modify it, and write it back while preserving formatting
29
+ - **Complete Coverage** - Every Notion block type supported with type safety
30
+
31
+ ---
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ pip install notionary
37
+ ```
38
+
39
+ Set up your [Notion integration](https://www.notion.so/profile/integrations) and configure your token:
40
+
41
+ ```bash
42
+ export NOTION_SECRET=your_integration_key
43
+ ```
44
+
45
+ ---
46
+
47
+ ## See It in Action
48
+
49
+ https://github.com/user-attachments/assets/da8b4691-bee4-4b0f-801e-dccacb630398
50
+
51
+ _Create rich database entries with properties, content, and beautiful formatting_
52
+
53
+ ---
54
+
55
+ ## Quick Start
56
+
57
+ ### Find → Create → Update Flow
58
+
59
+ ```python
60
+ from notionary import NotionPage
61
+
62
+ # Find pages by name with fuzzy matching
63
+ page = await NotionPage.from_title("Meeting Notes")
64
+
65
+ # Define rich content with extended markdown
66
+ content = """
67
+ ## Action Items
68
+ - [x] Review proposal
69
+ - [ ] Schedule meeting
70
+
71
+ [callout](Key decision made! "💡")
72
+
73
+ | Task | Owner | Deadline |
74
+ |------|-------|----------|
75
+ | Design Review | Alice | 2024-03-15 |
76
+ | Implementation | Bob | 2024-03-22 |
77
+
78
+ +++ Budget Details
79
+ See attached spreadsheet...
80
+ +++
81
+ """
82
+
83
+ await page.append_markdown(content)
84
+ ```
85
+
86
+ ### Complete Block Support
87
+
88
+ Every Notion block type with extended syntax:
89
+
90
+ | Block Type | Markdown Syntax | Use Case |
91
+ | ------------- | -------------------------------------------- | ---------------------------- |
92
+ | **Toggles** | `+++ Title\nContent\n+++` | Collapsible sections |
93
+ | **Columns** | `::: columns\n::: column\nContent\n:::\n:::` | Side-by-side layouts |
94
+ | **Tables** | Standard markdown tables | Structured data |
95
+ | **Media** | `[video](./file.mp4)(caption:Description)` | Auto-uploading files |
96
+ | **Code** | Standard code fences with captions | Code snippets |
97
+ | **Equations** | `$LaTeX$` | Mathematical expressions |
98
+ | **TOC** | `[toc]` | Auto-generated navigation |
99
+
100
+ ---
101
+
102
+ ## Key Features
103
+
104
+ <table>
105
+ <tr>
106
+ <td width="50%">
107
+
108
+ ### Smart Discovery
109
+
110
+ - Find pages/databases by name
111
+ - Fuzzy matching for approximate searches
112
+ - No more hunting for IDs or URLs
113
+
114
+ ### Extended Markdown
115
+
116
+ - Rich syntax beyond standard markdown
117
+ - Callouts, toggles, columns, media uploads
118
+ - Schema provided for AI agent integration
119
+
120
+ ### Modern Python
121
+
122
+ - Full async/await support
123
+ - Type hints throughout
124
+ - High-performance batch operations
125
+
126
+ </td>
127
+ <td width="50%">
128
+
129
+ ### Round-Trip Editing
130
+
131
+ - Read existing content as markdown
132
+ - Edit and modify preserving formatting
133
+ - Write back to Notion seamlessly
134
+
135
+ ### AI-Ready Architecture
136
+
137
+ - Schema-driven syntax for LLM prompts
138
+ - Perfect for AI content generation
139
+ - Handles complex nested structures
140
+
141
+ ### Complete Coverage
142
+
143
+ - Every Notion block type supported
144
+ - File uploads with automatic handling
145
+ - Database operations and properties
146
+
147
+ </td>
148
+ </tr>
149
+ </table>
150
+
151
+ ---
152
+
153
+ ## Examples & Documentation
154
+
155
+ ### Full Documentation
156
+
157
+ [**mathisarends.github.io/notionary**](https://mathisarends.github.io/notionary/) - Complete API reference, guides, and tutorials
158
+
159
+ ---
160
+
161
+ ## Contributing
162
+
163
+ We welcome contributions from the community! Whether you're:
164
+
165
+ - **Fixing bugs** - Help improve stability and reliability
166
+ - **Adding features** - Extend functionality for new use cases
167
+ - **Improving docs** - Make the library more accessible
168
+ - **Sharing examples** - Show creative applications and patterns
169
+
170
+ Check our [**Contributing Guide**](https://mathisarends.github.io/notionary/contributing/) to get started.
171
+
172
+ ---
173
+
174
+ <div align="center">
175
+
176
+ **Ready to revolutionize your Notion workflows?**
177
+
178
+ [📖 **Read the Docs**](https://mathisarends.github.io/notionary/) • [🚀 **Getting Started**](https://mathisarends.github.io/notionary/get-started/) • [💻 **Browse Examples**](examples/)
179
+
180
+ _Built with ❤️ for Python developers and AI agents_
181
+
182
+ ---
183
+
184
+ **Transform complex Notion API interactions into simple, powerful code.**
185
+
186
+ </div>
@@ -0,0 +1,7 @@
1
+ from .data_source.service import NotionDataSource
2
+ from .database.service import NotionDatabase
3
+ from .page.content.markdown.builder import MarkdownBuilder
4
+ from .page.service import NotionPage
5
+ from .workspace import NotionWorkspace
6
+
7
+ __all__ = ["MarkdownBuilder", "NotionDataSource", "NotionDatabase", "NotionPage", "NotionWorkspace", "NotionWorkspace"]
@@ -0,0 +1,5 @@
1
+ from .enums import CodingLanguage
2
+
3
+ # Import from schemas aswell
4
+
5
+ __all__ = ["CodingLanguage"]
@@ -0,0 +1,130 @@
1
+ from notionary.blocks.schemas import Block, BlockChildrenResponse, BlockCreatePayload
2
+ from notionary.http.client import NotionHttpClient
3
+ from notionary.shared.typings import JsonDict
4
+ from notionary.utils.decorators import time_execution_async
5
+ from notionary.utils.pagination import paginate_notion_api
6
+
7
+
8
+ class NotionBlockHttpClient(NotionHttpClient):
9
+ BATCH_SIZE = 100
10
+
11
+ async def get_block(self, block_id: str) -> Block:
12
+ response = await self.get(f"blocks/{block_id}")
13
+ return Block.model_validate(response)
14
+
15
+ async def delete_block(self, block_id: str) -> None:
16
+ self.logger.debug("Deleting block: %s", block_id)
17
+ await self.delete(f"blocks/{block_id}")
18
+
19
+ @time_execution_async()
20
+ async def get_block_tree(self, parent_block_id: str) -> list[Block]:
21
+ blocks_at_this_level = await self.get_all_block_children(parent_block_id)
22
+
23
+ for block in blocks_at_this_level:
24
+ if block.has_children:
25
+ nested_children = await self.get_block_tree(parent_block_id=block.id)
26
+ block.children = nested_children
27
+
28
+ return blocks_at_this_level
29
+
30
+ @time_execution_async()
31
+ async def get_all_block_children(self, parent_block_id: str) -> list[Block]:
32
+ self.logger.debug("Retrieving all children for block: %s", parent_block_id)
33
+
34
+ all_blocks = await paginate_notion_api(self.get_block_children, block_id=parent_block_id)
35
+
36
+ self.logger.debug("Retrieved %d total children for block %s", len(all_blocks), parent_block_id)
37
+ return all_blocks
38
+
39
+ async def get_block_children(
40
+ self, block_id: str, start_cursor: str | None = None, page_size: int = 100
41
+ ) -> BlockChildrenResponse:
42
+ self.logger.debug("Retrieving children of block: %s", block_id)
43
+
44
+ params = {"page_size": min(page_size, 100)}
45
+ if start_cursor:
46
+ params["start_cursor"] = start_cursor
47
+
48
+ response = await self.get(f"blocks/{block_id}/children", params=params)
49
+ return BlockChildrenResponse.model_validate(response)
50
+
51
+ async def append_block_children(
52
+ self,
53
+ block_id: str,
54
+ children: list[BlockCreatePayload],
55
+ insert_after_block_id: str | None = None,
56
+ ) -> BlockChildrenResponse | None:
57
+ if not children:
58
+ self.logger.warning("No children provided to append")
59
+ return None
60
+
61
+ self.logger.debug("Appending %d children to block: %s", len(children), block_id)
62
+
63
+ batches = self._split_into_batches(children)
64
+
65
+ if len(batches) == 1:
66
+ children_dicts = self._serialize_blocks(batches[0])
67
+ return await self._send_append_request(block_id, children_dicts, insert_after_block_id)
68
+
69
+ return await self._send_batched_append_requests(block_id, batches, insert_after_block_id)
70
+
71
+ def _split_into_batches(self, blocks: list[BlockCreatePayload]) -> list[list[BlockCreatePayload]]:
72
+ batches = []
73
+ for i in range(0, len(blocks), self.BATCH_SIZE):
74
+ batch = blocks[i : i + self.BATCH_SIZE]
75
+ batches.append(batch)
76
+ return batches
77
+
78
+ def _serialize_blocks(self, blocks: list[BlockCreatePayload]) -> list[JsonDict]:
79
+ return [block.model_dump(exclude_none=True) for block in blocks]
80
+
81
+ async def _send_append_request(
82
+ self, block_id: str, children: list[JsonDict], after_block_id: str | None = None
83
+ ) -> BlockChildrenResponse:
84
+ payload = {"children": children}
85
+ if after_block_id:
86
+ payload["after"] = after_block_id
87
+
88
+ response = await self.patch(f"blocks/{block_id}/children", payload)
89
+ return BlockChildrenResponse.model_validate(response)
90
+
91
+ async def _send_batched_append_requests(
92
+ self, block_id: str, batches: list[list[BlockCreatePayload]], initial_after_block_id: str | None = None
93
+ ) -> BlockChildrenResponse:
94
+ total_blocks = sum(len(batch) for batch in batches)
95
+ self.logger.info("Appending %d blocks in %d batches", total_blocks, len(batches))
96
+
97
+ all_responses = []
98
+ after_block_id = initial_after_block_id
99
+
100
+ for batch_index, batch in enumerate(batches, start=1):
101
+ self.logger.debug("Processing batch %d/%d (%d blocks)", batch_index, len(batches), len(batch))
102
+
103
+ children_dicts = self._serialize_blocks(batch)
104
+ response = await self._send_append_request(block_id, children_dicts, after_block_id)
105
+ all_responses.append(response)
106
+
107
+ if response.results:
108
+ after_block_id = response.results[-1].id
109
+
110
+ self.logger.debug("Completed batch %d/%d", batch_index, len(batches))
111
+
112
+ self.logger.info("Successfully appended all blocks in %d batches", len(batches))
113
+ return self._merge_responses(all_responses)
114
+
115
+ def _merge_responses(self, responses: list[BlockChildrenResponse]) -> BlockChildrenResponse:
116
+ if not responses:
117
+ raise ValueError("Cannot merge empty response list - this should never happen")
118
+
119
+ first_response = responses[0]
120
+ all_results = [block for response in responses for block in response.results]
121
+
122
+ return BlockChildrenResponse(
123
+ object=first_response.object,
124
+ results=all_results,
125
+ next_cursor=None,
126
+ has_more=False,
127
+ type=first_response.type,
128
+ block=first_response.block,
129
+ request_id=responses[-1].request_id,
130
+ )