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.
- notionary-0.3.0/.gitignore +94 -0
- {notionary-0.2.27 → notionary-0.3.0}/LICENSE +9 -9
- notionary-0.3.0/PKG-INFO +201 -0
- notionary-0.3.0/README.md +186 -0
- notionary-0.3.0/notionary/__init__.py +7 -0
- notionary-0.3.0/notionary/blocks/__init__.py +5 -0
- notionary-0.3.0/notionary/blocks/client.py +130 -0
- notionary-0.3.0/notionary/blocks/enums.py +167 -0
- notionary-0.3.0/notionary/blocks/rich_text/markdown_rich_text_converter.py +280 -0
- notionary-0.3.0/notionary/blocks/rich_text/models.py +178 -0
- notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/__init__.py +13 -0
- notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/data_source.py +32 -0
- notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
- notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
- notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
- notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
- notionary-0.3.0/notionary/blocks/rich_text/rich_text_markdown_converter.py +144 -0
- notionary-0.3.0/notionary/blocks/rich_text/rich_text_patterns.py +42 -0
- notionary-0.3.0/notionary/blocks/schemas.py +778 -0
- notionary-0.3.0/notionary/comments/__init__.py +5 -0
- notionary-0.3.0/notionary/comments/client.py +76 -0
- notionary-0.3.0/notionary/comments/factory.py +38 -0
- notionary-0.3.0/notionary/comments/models.py +7 -0
- notionary-0.3.0/notionary/comments/schemas.py +240 -0
- notionary-0.3.0/notionary/comments/service.py +34 -0
- notionary-0.3.0/notionary/data_source/http/client.py +11 -0
- notionary-0.3.0/notionary/data_source/http/data_source_instance_client.py +104 -0
- notionary-0.3.0/notionary/data_source/properties/schemas.py +402 -0
- notionary-0.3.0/notionary/data_source/query/builder.py +448 -0
- notionary-0.3.0/notionary/data_source/query/resolver.py +114 -0
- notionary-0.3.0/notionary/data_source/query/schema.py +302 -0
- notionary-0.3.0/notionary/data_source/query/validator.py +73 -0
- notionary-0.3.0/notionary/data_source/schema/registry.py +104 -0
- notionary-0.3.0/notionary/data_source/schema/service.py +136 -0
- notionary-0.3.0/notionary/data_source/schemas.py +27 -0
- notionary-0.3.0/notionary/data_source/service.py +377 -0
- notionary-0.3.0/notionary/database/client.py +43 -0
- notionary-0.3.0/notionary/database/database_metadata_update_client.py +19 -0
- notionary-0.3.0/notionary/database/schemas.py +29 -0
- notionary-0.3.0/notionary/database/service.py +168 -0
- notionary-0.3.0/notionary/exceptions/__init__.py +33 -0
- notionary-0.3.0/notionary/exceptions/api.py +41 -0
- notionary-0.3.0/notionary/exceptions/base.py +2 -0
- notionary-0.3.0/notionary/exceptions/block_parsing.py +16 -0
- notionary-0.3.0/notionary/exceptions/data_source/__init__.py +6 -0
- notionary-0.3.0/notionary/exceptions/data_source/builder.py +182 -0
- notionary-0.3.0/notionary/exceptions/data_source/properties.py +34 -0
- notionary-0.3.0/notionary/exceptions/properties.py +58 -0
- notionary-0.3.0/notionary/exceptions/search.py +57 -0
- {notionary-0.2.27 → notionary-0.3.0}/notionary/file_upload/client.py +18 -30
- {notionary-0.2.27 → notionary-0.3.0}/notionary/file_upload/models.py +7 -8
- notionary-0.2.27/notionary/file_upload/notion_file_upload.py → notionary-0.3.0/notionary/file_upload/service.py +29 -64
- notionary-0.3.0/notionary/http/client.py +204 -0
- notionary-0.3.0/notionary/http/models.py +50 -0
- notionary-0.3.0/notionary/page/blocks/client.py +1 -0
- notionary-0.3.0/notionary/page/content/factory.py +73 -0
- notionary-0.3.0/notionary/page/content/markdown/__init__.py +5 -0
- notionary-0.3.0/notionary/page/content/markdown/builder.py +226 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/__init__.py +52 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/audio.py +23 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/base.py +12 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/bookmark.py +25 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/bulleted_list.py +41 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/callout.py +34 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/code.py +28 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/columns.py +69 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/container.py +64 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/divider.py +14 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/embed.py +23 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/equation.py +19 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/file.py +23 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/heading.py +36 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/image.py +23 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/mixins/__init__.py +5 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/numbered_list.py +38 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/paragraph.py +14 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/pdf.py +23 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/quote.py +27 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/space.py +14 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/table.py +45 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/todo.py +38 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/toggle.py +27 -0
- notionary-0.3.0/notionary/page/content/markdown/nodes/video.py +23 -0
- notionary-0.3.0/notionary/page/content/parser/context.py +126 -0
- notionary-0.3.0/notionary/page/content/parser/factory.py +210 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/__init__.py +58 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/audio.py +40 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/base.py +30 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/bookmark.py +33 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/breadcrumb.py +33 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/bulleted_list.py +85 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/callout.py +100 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/caption.py +55 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/code.py +81 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/column.py +76 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/column_list.py +81 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/divider.py +33 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/embed.py +33 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/equation.py +65 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/file.py +42 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/heading.py +115 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/image.py +42 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/numbered_list.py +89 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/paragraph.py +37 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/pdf.py +42 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/quote.py +125 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/space.py +41 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/table.py +144 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/table_of_contents.py +32 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/todo.py +96 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/toggle.py +70 -0
- notionary-0.3.0/notionary/page/content/parser/parsers/video.py +42 -0
- notionary-0.3.0/notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
- notionary-0.3.0/notionary/page/content/parser/post_processing/handlers/rich_text_length.py +95 -0
- notionary-0.3.0/notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +114 -0
- notionary-0.3.0/notionary/page/content/parser/post_processing/port.py +9 -0
- notionary-0.3.0/notionary/page/content/parser/post_processing/service.py +16 -0
- notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/__init__.py +11 -0
- notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +130 -0
- notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/indentation.py +84 -0
- notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
- notionary-0.3.0/notionary/page/content/parser/pre_processsing/handlers/whitespace.py +73 -0
- notionary-0.3.0/notionary/page/content/parser/pre_processsing/service.py +15 -0
- notionary-0.3.0/notionary/page/content/parser/service.py +78 -0
- notionary-0.3.0/notionary/page/content/renderer/context.py +51 -0
- notionary-0.3.0/notionary/page/content/renderer/factory.py +231 -0
- notionary-0.3.0/notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
- notionary-0.3.0/notionary/page/content/renderer/post_processing/handlers/numbered_list.py +156 -0
- notionary-0.3.0/notionary/page/content/renderer/post_processing/port.py +7 -0
- notionary-0.3.0/notionary/page/content/renderer/post_processing/service.py +15 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/__init__.py +55 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/audio.py +31 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/base.py +31 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/bookmark.py +25 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/callout.py +50 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/captioned_block.py +58 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/code.py +34 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/column.py +53 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/column_list.py +44 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/divider.py +22 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/embed.py +25 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/equation.py +37 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/fallback.py +24 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/file.py +40 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/heading.py +95 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/image.py +31 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/numbered_list.py +42 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/paragraph.py +40 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/pdf.py +31 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/quote.py +49 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/table.py +115 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/table_row.py +17 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/todo.py +56 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/toggle.py +52 -0
- notionary-0.3.0/notionary/page/content/renderer/renderers/video.py +31 -0
- notionary-0.3.0/notionary/page/content/renderer/service.py +50 -0
- notionary-0.3.0/notionary/page/content/service.py +68 -0
- notionary-0.3.0/notionary/page/content/syntax/__init__.py +4 -0
- notionary-0.3.0/notionary/page/content/syntax/grammar.py +10 -0
- notionary-0.3.0/notionary/page/content/syntax/models.py +66 -0
- notionary-0.3.0/notionary/page/content/syntax/registry.py +393 -0
- {notionary-0.2.27 → notionary-0.3.0}/notionary/page/page_context.py +7 -16
- notionary-0.3.0/notionary/page/page_http_client.py +15 -0
- notionary-0.3.0/notionary/page/page_metadata_update_client.py +19 -0
- notionary-0.3.0/notionary/page/properties/client.py +144 -0
- notionary-0.3.0/notionary/page/properties/factory.py +26 -0
- notionary-0.3.0/notionary/page/properties/models.py +308 -0
- notionary-0.3.0/notionary/page/properties/service.py +261 -0
- notionary-0.3.0/notionary/page/schemas.py +13 -0
- notionary-0.3.0/notionary/page/service.py +225 -0
- notionary-0.3.0/notionary/shared/entity/client.py +29 -0
- notionary-0.3.0/notionary/shared/entity/dto_parsers.py +53 -0
- notionary-0.3.0/notionary/shared/entity/entity_metadata_update_client.py +41 -0
- notionary-0.3.0/notionary/shared/entity/schemas.py +45 -0
- notionary-0.3.0/notionary/shared/entity/service.py +171 -0
- notionary-0.3.0/notionary/shared/models/cover.py +20 -0
- notionary-0.3.0/notionary/shared/models/file.py +21 -0
- notionary-0.3.0/notionary/shared/models/icon.py +28 -0
- notionary-0.3.0/notionary/shared/models/parent.py +41 -0
- notionary-0.3.0/notionary/shared/properties/type.py +30 -0
- notionary-0.3.0/notionary/shared/typings.py +3 -0
- notionary-0.3.0/notionary/user/__init__.py +7 -0
- notionary-0.3.0/notionary/user/base.py +138 -0
- notionary-0.3.0/notionary/user/bot.py +70 -0
- notionary-0.3.0/notionary/user/client.py +39 -0
- notionary-0.3.0/notionary/user/person.py +41 -0
- notionary-0.3.0/notionary/user/schemas.py +67 -0
- notionary-0.3.0/notionary/user/service.py +65 -0
- notionary-0.3.0/notionary/utils/date.py +51 -0
- notionary-0.3.0/notionary/utils/decorators.py +122 -0
- notionary-0.3.0/notionary/utils/fuzzy.py +68 -0
- notionary-0.3.0/notionary/utils/mixins/logging.py +58 -0
- notionary-0.3.0/notionary/utils/pagination.py +100 -0
- notionary-0.3.0/notionary/utils/uuid_utils.py +20 -0
- notionary-0.3.0/notionary/workspace/__init__.py +4 -0
- notionary-0.3.0/notionary/workspace/client.py +62 -0
- notionary-0.3.0/notionary/workspace/query/__init__.py +3 -0
- notionary-0.3.0/notionary/workspace/query/builder.py +60 -0
- notionary-0.3.0/notionary/workspace/query/models.py +61 -0
- notionary-0.3.0/notionary/workspace/query/service.py +100 -0
- notionary-0.3.0/notionary/workspace/schemas.py +21 -0
- notionary-0.3.0/notionary/workspace/service.py +116 -0
- notionary-0.3.0/pyproject.toml +72 -0
- notionary-0.2.27/PKG-INFO +0 -270
- notionary-0.2.27/README.md +0 -246
- notionary-0.2.27/notionary/__init__.py +0 -22
- notionary-0.2.27/notionary/base_notion_client.py +0 -219
- notionary-0.2.27/notionary/blocks/__init__.py +0 -5
- notionary-0.2.27/notionary/blocks/_bootstrap.py +0 -271
- notionary-0.2.27/notionary/blocks/audio/__init__.py +0 -11
- notionary-0.2.27/notionary/blocks/audio/audio_element.py +0 -158
- notionary-0.2.27/notionary/blocks/audio/audio_markdown_node.py +0 -24
- notionary-0.2.27/notionary/blocks/audio/audio_models.py +0 -10
- notionary-0.2.27/notionary/blocks/base_block_element.py +0 -42
- notionary-0.2.27/notionary/blocks/bookmark/__init__.py +0 -12
- notionary-0.2.27/notionary/blocks/bookmark/bookmark_element.py +0 -83
- notionary-0.2.27/notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
- notionary-0.2.27/notionary/blocks/bookmark/bookmark_models.py +0 -15
- notionary-0.2.27/notionary/blocks/breadcrumbs/__init__.py +0 -15
- notionary-0.2.27/notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
- notionary-0.2.27/notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
- notionary-0.2.27/notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
- notionary-0.2.27/notionary/blocks/bulleted_list/__init__.py +0 -15
- notionary-0.2.27/notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
- notionary-0.2.27/notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
- notionary-0.2.27/notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
- notionary-0.2.27/notionary/blocks/callout/__init__.py +0 -12
- notionary-0.2.27/notionary/blocks/callout/callout_element.py +0 -99
- notionary-0.2.27/notionary/blocks/callout/callout_markdown_node.py +0 -19
- notionary-0.2.27/notionary/blocks/callout/callout_models.py +0 -33
- notionary-0.2.27/notionary/blocks/child_database/__init__.py +0 -14
- notionary-0.2.27/notionary/blocks/child_database/child_database_element.py +0 -59
- notionary-0.2.27/notionary/blocks/child_database/child_database_models.py +0 -12
- notionary-0.2.27/notionary/blocks/child_page/__init__.py +0 -9
- notionary-0.2.27/notionary/blocks/child_page/child_page_element.py +0 -94
- notionary-0.2.27/notionary/blocks/child_page/child_page_models.py +0 -12
- notionary-0.2.27/notionary/blocks/client.py +0 -256
- notionary-0.2.27/notionary/blocks/code/__init__.py +0 -11
- notionary-0.2.27/notionary/blocks/code/code_element.py +0 -149
- notionary-0.2.27/notionary/blocks/code/code_markdown_node.py +0 -80
- notionary-0.2.27/notionary/blocks/code/code_models.py +0 -94
- notionary-0.2.27/notionary/blocks/column/__init__.py +0 -25
- notionary-0.2.27/notionary/blocks/column/column_element.py +0 -65
- notionary-0.2.27/notionary/blocks/column/column_list_element.py +0 -52
- notionary-0.2.27/notionary/blocks/column/column_list_markdown_node.py +0 -34
- notionary-0.2.27/notionary/blocks/column/column_markdown_node.py +0 -42
- notionary-0.2.27/notionary/blocks/column/column_models.py +0 -26
- notionary-0.2.27/notionary/blocks/divider/__init__.py +0 -12
- notionary-0.2.27/notionary/blocks/divider/divider_element.py +0 -41
- notionary-0.2.27/notionary/blocks/divider/divider_markdown_node.py +0 -11
- notionary-0.2.27/notionary/blocks/divider/divider_models.py +0 -12
- notionary-0.2.27/notionary/blocks/embed/__init__.py +0 -12
- notionary-0.2.27/notionary/blocks/embed/embed_element.py +0 -98
- notionary-0.2.27/notionary/blocks/embed/embed_markdown_node.py +0 -19
- notionary-0.2.27/notionary/blocks/embed/embed_models.py +0 -14
- notionary-0.2.27/notionary/blocks/equation/__init__.py +0 -13
- notionary-0.2.27/notionary/blocks/equation/equation_element.py +0 -133
- notionary-0.2.27/notionary/blocks/equation/equation_element_markdown_node.py +0 -23
- notionary-0.2.27/notionary/blocks/equation/equation_models.py +0 -11
- notionary-0.2.27/notionary/blocks/file/__init__.py +0 -23
- notionary-0.2.27/notionary/blocks/file/file_element.py +0 -133
- notionary-0.2.27/notionary/blocks/file/file_element_markdown_node.py +0 -24
- notionary-0.2.27/notionary/blocks/file/file_element_models.py +0 -39
- notionary-0.2.27/notionary/blocks/heading/__init__.py +0 -19
- notionary-0.2.27/notionary/blocks/heading/heading_element.py +0 -112
- notionary-0.2.27/notionary/blocks/heading/heading_markdown_node.py +0 -16
- notionary-0.2.27/notionary/blocks/heading/heading_models.py +0 -29
- notionary-0.2.27/notionary/blocks/image_block/__init__.py +0 -11
- notionary-0.2.27/notionary/blocks/image_block/image_element.py +0 -130
- notionary-0.2.27/notionary/blocks/image_block/image_markdown_node.py +0 -25
- notionary-0.2.27/notionary/blocks/image_block/image_models.py +0 -10
- notionary-0.2.27/notionary/blocks/markdown/markdown_builder.py +0 -525
- notionary-0.2.27/notionary/blocks/markdown/markdown_document_model.py +0 -0
- notionary-0.2.27/notionary/blocks/markdown/markdown_node.py +0 -25
- notionary-0.2.27/notionary/blocks/mixins/captions/__init__.py +0 -4
- notionary-0.2.27/notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
- notionary-0.2.27/notionary/blocks/mixins/captions/caption_mixin.py +0 -92
- notionary-0.2.27/notionary/blocks/mixins/file_upload/__init__.py +0 -3
- notionary-0.2.27/notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
- notionary-0.2.27/notionary/blocks/models.py +0 -174
- notionary-0.2.27/notionary/blocks/numbered_list/__init__.py +0 -16
- notionary-0.2.27/notionary/blocks/numbered_list/numbered_list_element.py +0 -65
- notionary-0.2.27/notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
- notionary-0.2.27/notionary/blocks/numbered_list/numbered_list_models.py +0 -17
- notionary-0.2.27/notionary/blocks/paragraph/__init__.py +0 -15
- notionary-0.2.27/notionary/blocks/paragraph/paragraph_element.py +0 -58
- notionary-0.2.27/notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
- notionary-0.2.27/notionary/blocks/paragraph/paragraph_models.py +0 -16
- notionary-0.2.27/notionary/blocks/pdf/__init__.py +0 -11
- notionary-0.2.27/notionary/blocks/pdf/pdf_element.py +0 -146
- notionary-0.2.27/notionary/blocks/pdf/pdf_markdown_node.py +0 -24
- notionary-0.2.27/notionary/blocks/pdf/pdf_models.py +0 -11
- notionary-0.2.27/notionary/blocks/quote/__init__.py +0 -14
- notionary-0.2.27/notionary/blocks/quote/quote_element.py +0 -75
- notionary-0.2.27/notionary/blocks/quote/quote_markdown_node.py +0 -16
- notionary-0.2.27/notionary/blocks/quote/quote_models.py +0 -18
- notionary-0.2.27/notionary/blocks/registry/__init__.py +0 -3
- notionary-0.2.27/notionary/blocks/registry/block_registry.py +0 -150
- notionary-0.2.27/notionary/blocks/rich_text/__init__.py +0 -33
- notionary-0.2.27/notionary/blocks/rich_text/rich_text_models.py +0 -221
- notionary-0.2.27/notionary/blocks/rich_text/text_inline_formatter.py +0 -456
- notionary-0.2.27/notionary/blocks/syntax_prompt_builder.py +0 -137
- notionary-0.2.27/notionary/blocks/table/__init__.py +0 -19
- notionary-0.2.27/notionary/blocks/table/table_element.py +0 -225
- notionary-0.2.27/notionary/blocks/table/table_markdown_node.py +0 -42
- notionary-0.2.27/notionary/blocks/table/table_models.py +0 -28
- notionary-0.2.27/notionary/blocks/table_of_contents/__init__.py +0 -17
- notionary-0.2.27/notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
- notionary-0.2.27/notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
- notionary-0.2.27/notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
- notionary-0.2.27/notionary/blocks/todo/__init__.py +0 -12
- notionary-0.2.27/notionary/blocks/todo/todo_element.py +0 -81
- notionary-0.2.27/notionary/blocks/todo/todo_markdown_node.py +0 -21
- notionary-0.2.27/notionary/blocks/todo/todo_models.py +0 -18
- notionary-0.2.27/notionary/blocks/toggle/__init__.py +0 -12
- notionary-0.2.27/notionary/blocks/toggle/toggle_element.py +0 -112
- notionary-0.2.27/notionary/blocks/toggle/toggle_markdown_node.py +0 -31
- notionary-0.2.27/notionary/blocks/toggle/toggle_models.py +0 -17
- notionary-0.2.27/notionary/blocks/toggleable_heading/__init__.py +0 -11
- notionary-0.2.27/notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
- notionary-0.2.27/notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
- notionary-0.2.27/notionary/blocks/types.py +0 -130
- notionary-0.2.27/notionary/blocks/video/__init__.py +0 -11
- notionary-0.2.27/notionary/blocks/video/video_element.py +0 -187
- notionary-0.2.27/notionary/blocks/video/video_element_models.py +0 -10
- notionary-0.2.27/notionary/blocks/video/video_markdown_node.py +0 -26
- notionary-0.2.27/notionary/comments/__init__.py +0 -26
- notionary-0.2.27/notionary/comments/client.py +0 -211
- notionary-0.2.27/notionary/comments/models.py +0 -129
- notionary-0.2.27/notionary/database/__init__.py +0 -4
- notionary-0.2.27/notionary/database/client.py +0 -148
- notionary-0.2.27/notionary/database/database.py +0 -480
- notionary-0.2.27/notionary/database/database_filter_builder.py +0 -173
- notionary-0.2.27/notionary/database/database_provider.py +0 -227
- notionary-0.2.27/notionary/database/exceptions.py +0 -13
- notionary-0.2.27/notionary/database/models.py +0 -337
- notionary-0.2.27/notionary/database/notion_database.py +0 -487
- notionary-0.2.27/notionary/file_upload/__init__.py +0 -7
- notionary-0.2.27/notionary/page/client.py +0 -124
- notionary-0.2.27/notionary/page/markdown_whitespace_processor.py +0 -129
- notionary-0.2.27/notionary/page/models.py +0 -322
- notionary-0.2.27/notionary/page/notion_page.py +0 -712
- notionary-0.2.27/notionary/page/page_content_deleting_service.py +0 -117
- notionary-0.2.27/notionary/page/page_content_writer.py +0 -80
- notionary-0.2.27/notionary/page/property_formatter.py +0 -99
- notionary-0.2.27/notionary/page/reader/handler/__init__.py +0 -19
- notionary-0.2.27/notionary/page/reader/handler/base_block_renderer.py +0 -44
- notionary-0.2.27/notionary/page/reader/handler/block_processing_context.py +0 -35
- notionary-0.2.27/notionary/page/reader/handler/block_rendering_context.py +0 -48
- notionary-0.2.27/notionary/page/reader/handler/column_list_renderer.py +0 -51
- notionary-0.2.27/notionary/page/reader/handler/column_renderer.py +0 -60
- notionary-0.2.27/notionary/page/reader/handler/equation_renderer.py +0 -0
- notionary-0.2.27/notionary/page/reader/handler/line_renderer.py +0 -73
- notionary-0.2.27/notionary/page/reader/handler/numbered_list_renderer.py +0 -85
- notionary-0.2.27/notionary/page/reader/handler/toggle_renderer.py +0 -69
- notionary-0.2.27/notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
- notionary-0.2.27/notionary/page/reader/page_content_retriever.py +0 -81
- notionary-0.2.27/notionary/page/search_filter_builder.py +0 -132
- notionary-0.2.27/notionary/page/utils.py +0 -60
- notionary-0.2.27/notionary/page/writer/handler/__init__.py +0 -24
- notionary-0.2.27/notionary/page/writer/handler/code_handler.py +0 -72
- notionary-0.2.27/notionary/page/writer/handler/column_handler.py +0 -141
- notionary-0.2.27/notionary/page/writer/handler/column_list_handler.py +0 -139
- notionary-0.2.27/notionary/page/writer/handler/equation_handler.py +0 -74
- notionary-0.2.27/notionary/page/writer/handler/line_handler.py +0 -35
- notionary-0.2.27/notionary/page/writer/handler/line_processing_context.py +0 -54
- notionary-0.2.27/notionary/page/writer/handler/regular_line_handler.py +0 -86
- notionary-0.2.27/notionary/page/writer/handler/table_handler.py +0 -66
- notionary-0.2.27/notionary/page/writer/handler/toggle_handler.py +0 -159
- notionary-0.2.27/notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
- notionary-0.2.27/notionary/page/writer/markdown_to_notion_converter.py +0 -139
- notionary-0.2.27/notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
- notionary-0.2.27/notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
- notionary-0.2.27/notionary/page/writer/notion_text_length_processor.py +0 -150
- notionary-0.2.27/notionary/schemas/__init__.py +0 -3
- notionary-0.2.27/notionary/schemas/base.py +0 -73
- notionary-0.2.27/notionary/shared/__init__.py +0 -3
- notionary-0.2.27/notionary/shared/name_to_id_resolver.py +0 -203
- notionary-0.2.27/notionary/telemetry/__init__.py +0 -19
- notionary-0.2.27/notionary/telemetry/service.py +0 -136
- notionary-0.2.27/notionary/telemetry/views.py +0 -73
- notionary-0.2.27/notionary/user/__init__.py +0 -11
- notionary-0.2.27/notionary/user/base_notion_user.py +0 -53
- notionary-0.2.27/notionary/user/client.py +0 -128
- notionary-0.2.27/notionary/user/models.py +0 -84
- notionary-0.2.27/notionary/user/notion_bot_user.py +0 -226
- notionary-0.2.27/notionary/user/notion_user.py +0 -255
- notionary-0.2.27/notionary/user/notion_user_manager.py +0 -101
- notionary-0.2.27/notionary/util/__init__.py +0 -15
- notionary-0.2.27/notionary/util/concurrency_limiter.py +0 -0
- notionary-0.2.27/notionary/util/factory_decorator.py +0 -0
- notionary-0.2.27/notionary/util/factory_only.py +0 -37
- notionary-0.2.27/notionary/util/fuzzy.py +0 -75
- notionary-0.2.27/notionary/util/logging_mixin.py +0 -59
- notionary-0.2.27/notionary/util/page_id_utils.py +0 -27
- notionary-0.2.27/notionary/util/singleton.py +0 -18
- notionary-0.2.27/notionary/util/singleton_metaclass.py +0 -22
- notionary-0.2.27/notionary/workspace.py +0 -105
- notionary-0.2.27/pyproject.toml +0 -35
- {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.
|
notionary-0.3.0/PKG-INFO
ADDED
|
@@ -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
|
+
[](https://www.python.org/downloads/)
|
|
27
|
+
[](LICENSE)
|
|
28
|
+
[](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
|
+
[](https://www.python.org/downloads/)
|
|
12
|
+
[](LICENSE)
|
|
13
|
+
[](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,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
|
+
)
|