notionary 0.2.23__tar.gz → 0.2.24__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.2.23 → notionary-0.2.24}/PKG-INFO +16 -1
- {notionary-0.2.23 → notionary-0.2.24}/README.md +14 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/__init__.py +1 -1
- notionary-0.2.24/notionary/blocks/__init__.py +5 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/audio/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/audio/audio_element.py +158 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/audio/audio_markdown_node.py +4 -17
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bookmark/__init__.py +0 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bookmark/bookmark_markdown_node.py +5 -21
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/breadcrumbs/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +13 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bulleted_list/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +20 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bulleted_list/bulleted_list_models.py +0 -1
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/callout/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/callout/callout_markdown_node.py +19 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/callout/callout_models.py +3 -4
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/code/code_markdown_node.py +5 -19
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/__init__.py +0 -4
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_list_markdown_node.py +3 -19
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_markdown_node.py +4 -21
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/divider/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/divider/divider_markdown_node.py +11 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/embed/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/embed/embed_markdown_node.py +19 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/equation/__init__.py +0 -1
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/equation/equation_element_markdown_node.py +3 -15
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/file/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/file/file_element.py +133 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/file/file_element_markdown_node.py +4 -17
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/heading/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/heading/heading_markdown_node.py +16 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/heading/heading_models.py +3 -3
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/image_block/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/image_block/image_element.py +130 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/image_block/image_markdown_node.py +5 -20
- {notionary-0.2.23/notionary → notionary-0.2.24/notionary/blocks}/markdown/markdown_builder.py +29 -233
- notionary-0.2.24/notionary/blocks/markdown/markdown_node.py +25 -0
- notionary-0.2.24/notionary/blocks/mixins/file_upload/__init__.py +3 -0
- notionary-0.2.24/notionary/blocks/mixins/file_upload/file_upload_mixin.py +320 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/numbered_list/__init__.py +0 -1
- notionary-0.2.24/notionary/blocks/numbered_list/numbered_list_markdown_node.py +17 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/numbered_list/numbered_list_models.py +3 -3
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/paragraph/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/paragraph/paragraph_markdown_node.py +16 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/pdf/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/pdf/pdf_element.py +146 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/pdf/pdf_markdown_node.py +5 -18
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/quote/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/quote/quote_markdown_node.py +16 -0
- notionary-0.2.24/notionary/blocks/registry/__init__.py +3 -0
- notionary-0.2.24/notionary/blocks/registry/block_registry.py +150 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table/__init__.py +0 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table/table_markdown_node.py +17 -16
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table_of_contents/__init__.py +0 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table_of_contents/table_of_contents_element.py +27 -15
- notionary-0.2.24/notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +21 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table_of_contents/table_of_contents_models.py +2 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/todo/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/todo/todo_markdown_node.py +21 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/todo/todo_models.py +2 -3
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggle/__init__.py +0 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggle/toggle_markdown_node.py +5 -19
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggleable_heading/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +34 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/video/__init__.py +0 -2
- notionary-0.2.24/notionary/blocks/video/video_element.py +187 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/video/video_markdown_node.py +4 -15
- {notionary-0.2.23 → notionary-0.2.24}/notionary/comments/client.py +1 -1
- {notionary-0.2.23 → notionary-0.2.24}/notionary/file_upload/client.py +3 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/file_upload/models.py +10 -1
- {notionary-0.2.23 → notionary-0.2.24}/notionary/file_upload/notion_file_upload.py +5 -5
- notionary-0.2.24/notionary/page/markdown_whitespace_processor.py +129 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/notion_page.py +35 -40
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/page_content_deleting_service.py +1 -1
- notionary-0.2.24/notionary/page/page_content_writer.py +80 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/page_context.py +0 -5
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/column_list_renderer.py +2 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/column_renderer.py +2 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/line_renderer.py +2 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/toggle_renderer.py +2 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/toggleable_heading_renderer.py +2 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/toggle_handler.py +8 -4
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/toggleable_heading_handler.py +3 -2
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/markdown_to_notion_converter.py +74 -30
- notionary-0.2.24/notionary/schemas/__init__.py +3 -0
- notionary-0.2.24/notionary/schemas/base.py +73 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/shared/__init__.py +1 -3
- {notionary-0.2.23 → notionary-0.2.24}/pyproject.toml +3 -1
- notionary-0.2.23/notionary/blocks/__init__.py +0 -3
- notionary-0.2.23/notionary/blocks/audio/audio_element.py +0 -115
- notionary-0.2.23/notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -32
- notionary-0.2.23/notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -34
- notionary-0.2.23/notionary/blocks/callout/callout_markdown_node.py +0 -33
- notionary-0.2.23/notionary/blocks/divider/divider_markdown_node.py +0 -25
- notionary-0.2.23/notionary/blocks/embed/embed_markdown_node.py +0 -32
- notionary-0.2.23/notionary/blocks/file/file_element.py +0 -112
- notionary-0.2.23/notionary/blocks/guards.py +0 -22
- notionary-0.2.23/notionary/blocks/heading/heading_markdown_node.py +0 -30
- notionary-0.2.23/notionary/blocks/image_block/image_element.py +0 -89
- notionary-0.2.23/notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -31
- notionary-0.2.23/notionary/blocks/paragraph/paragraph_markdown_node.py +0 -26
- notionary-0.2.23/notionary/blocks/pdf/pdf_element.py +0 -97
- notionary-0.2.23/notionary/blocks/quote/quote_markdown_node.py +0 -26
- notionary-0.2.23/notionary/blocks/registry/__init__.py +0 -4
- notionary-0.2.23/notionary/blocks/registry/block_registry.py +0 -95
- notionary-0.2.23/notionary/blocks/registry/block_registry_builder.py +0 -264
- notionary-0.2.23/notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -35
- notionary-0.2.23/notionary/blocks/todo/todo_markdown_node.py +0 -32
- notionary-0.2.23/notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -51
- notionary-0.2.23/notionary/blocks/video/video_element.py +0 -111
- notionary-0.2.23/notionary/markdown/makdown_document_model.py +0 -0
- notionary-0.2.23/notionary/markdown/markdown_document_model.py +0 -228
- notionary-0.2.23/notionary/markdown/markdown_node.py +0 -30
- notionary-0.2.23/notionary/models/notion_database_response.py +0 -0
- notionary-0.2.23/notionary/page/page_content_writer.py +0 -177
- notionary-0.2.23/notionary/page/writer/markdown_to_notion_formatting_post_processor.py +0 -73
- notionary-0.2.23/notionary/page/writer/markdown_to_notion_post_processor.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/LICENSE +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/base_notion_client.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/_bootstrap.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/audio/audio_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/base_block_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bookmark/bookmark_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bookmark/bookmark_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bulleted_list/bulleted_list_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/callout/callout_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_database/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_database/child_database_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_database/child_database_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_page/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_page/child_page_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/child_page/child_page_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/client.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/code/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/code/code_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/code/code_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_list_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/column/column_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/divider/divider_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/divider/divider_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/embed/embed_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/embed/embed_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/equation/equation_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/equation/equation_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/file/file_element_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/heading/heading_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/image_block/image_models.py +0 -0
- /notionary-0.2.23/notionary/database/factory.py → /notionary-0.2.24/notionary/blocks/markdown/markdown_document_model.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/mixins/captions/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/mixins/captions/caption_mixin.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/numbered_list/numbered_list_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/paragraph/paragraph_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/paragraph/paragraph_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/pdf/pdf_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/quote/quote_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/quote/quote_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/rich_text/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/rich_text/rich_text_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/rich_text/text_inline_formatter.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/syntax_prompt_builder.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table/table_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/table/table_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/todo/todo_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggle/toggle_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggle/toggle_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/types.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/video/video_element_models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/comments/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/comments/models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/database/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/database/client.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/database/database.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/database/database_filter_builder.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/database/database_provider.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/database/exceptions.py +0 -0
- /notionary-0.2.23/notionary/markdown/___init__.py → /notionary-0.2.24/notionary/database/factory.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/database/models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/database/notion_database.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/file_upload/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/client.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/property_formatter.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/base_block_renderer.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/block_processing_context.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/block_rendering_context.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/equation_renderer.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/handler/numbered_list_renderer.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/reader/page_content_retriever.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/search_filter_builder.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/utils.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/code_handler.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/column_handler.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/column_list_handler.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/equation_handler.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/line_handler.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/line_processing_context.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/regular_line_handler.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/handler/table_handler.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/markdown_to_notion_converter_context.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/page/writer/notion_text_length_processor.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/shared/name_to_id_resolver.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/telemetry/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/telemetry/service.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/telemetry/views.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/user/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/user/base_notion_user.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/user/client.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/user/models.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/user/notion_bot_user.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/user/notion_user.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/user/notion_user_manager.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/util/__init__.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/util/concurrency_limiter.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/util/factory_decorator.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/util/factory_only.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/util/fuzzy.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/util/logging_mixin.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/util/page_id_utils.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/util/singleton.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/util/singleton_metaclass.py +0 -0
- {notionary-0.2.23 → notionary-0.2.24}/notionary/workspace.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: notionary
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.24
|
4
4
|
Summary: Python library for programmatic Notion workspace management - databases, pages, and content with advanced Markdown support
|
5
5
|
License: MIT
|
6
6
|
Author: Mathis Arends
|
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
16
|
+
Requires-Dist: aiofiles (>=24.1.0,<25.0.0)
|
16
17
|
Requires-Dist: httpx (>=0.28.0)
|
17
18
|
Requires-Dist: posthog (>=6.3.1,<7.0.0)
|
18
19
|
Requires-Dist: pydantic (>=2.11.4)
|
@@ -64,6 +65,13 @@ NOTION_SECRET=your_integration_key
|
|
64
65
|
|
65
66
|
### Simple Flow: Find → Create → Update
|
66
67
|
|
68
|
+
<video width="100%" controls>
|
69
|
+
<source src="./static/demo.mp4" type="video/mp4">
|
70
|
+
Your browser does not support the video tag.
|
71
|
+
</video>
|
72
|
+
|
73
|
+
_Demo: Converting markdown to structured Notion content with callouts, columns, and tables_
|
74
|
+
|
67
75
|
```python
|
68
76
|
import asyncio
|
69
77
|
from notionary import NotionPage, NotionDatabase
|
@@ -111,6 +119,13 @@ asyncio.run(main())
|
|
111
119
|
|
112
120
|
### Create Rich Database Entries
|
113
121
|
|
122
|
+
<video width="100%" controls>
|
123
|
+
<source src="./static/create_page_in_database_demo.mp4" type="video/mp4">
|
124
|
+
Your browser does not support the video tag.
|
125
|
+
</video>
|
126
|
+
|
127
|
+
_Demo: Creating a styled project page in a Notion database with properties, content, and rich formatting_
|
128
|
+
|
114
129
|
```python
|
115
130
|
# Work with databases - connect and create styled entries
|
116
131
|
db = await NotionDatabase.from_database_name("Projects")
|
@@ -42,6 +42,13 @@ NOTION_SECRET=your_integration_key
|
|
42
42
|
|
43
43
|
### Simple Flow: Find → Create → Update
|
44
44
|
|
45
|
+
<video width="100%" controls>
|
46
|
+
<source src="./static/demo.mp4" type="video/mp4">
|
47
|
+
Your browser does not support the video tag.
|
48
|
+
</video>
|
49
|
+
|
50
|
+
_Demo: Converting markdown to structured Notion content with callouts, columns, and tables_
|
51
|
+
|
45
52
|
```python
|
46
53
|
import asyncio
|
47
54
|
from notionary import NotionPage, NotionDatabase
|
@@ -89,6 +96,13 @@ asyncio.run(main())
|
|
89
96
|
|
90
97
|
### Create Rich Database Entries
|
91
98
|
|
99
|
+
<video width="100%" controls>
|
100
|
+
<source src="./static/create_page_in_database_demo.mp4" type="video/mp4">
|
101
|
+
Your browser does not support the video tag.
|
102
|
+
</video>
|
103
|
+
|
104
|
+
_Demo: Creating a styled project page in a Notion database with properties, content, and rich formatting_
|
105
|
+
|
92
106
|
```python
|
93
107
|
# Work with databases - connect and create styled entries
|
94
108
|
db = await NotionDatabase.from_database_name("Projects")
|
@@ -4,7 +4,7 @@ bootstrap_blocks()
|
|
4
4
|
|
5
5
|
from .database import DatabaseFilterBuilder, NotionDatabase
|
6
6
|
from .file_upload import NotionFileUpload
|
7
|
-
from .markdown.markdown_builder import MarkdownBuilder
|
7
|
+
from .blocks.markdown.markdown_builder import MarkdownBuilder
|
8
8
|
from .page.notion_page import NotionPage
|
9
9
|
from .user import NotionBotUser, NotionUser, NotionUserManager
|
10
10
|
from .workspace import NotionWorkspace
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from notionary.blocks.audio.audio_element import AudioElement
|
2
2
|
from notionary.blocks.audio.audio_markdown_node import (
|
3
|
-
AudioMarkdownBlockParams,
|
4
3
|
AudioMarkdownNode,
|
5
4
|
)
|
6
5
|
from notionary.blocks.audio.audio_models import CreateAudioBlock
|
@@ -9,5 +8,4 @@ __all__ = [
|
|
9
8
|
"AudioElement",
|
10
9
|
"CreateAudioBlock",
|
11
10
|
"AudioMarkdownNode",
|
12
|
-
"AudioMarkdownBlockParams",
|
13
11
|
]
|
@@ -0,0 +1,158 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import re
|
4
|
+
from pathlib import Path
|
5
|
+
from typing import Optional
|
6
|
+
|
7
|
+
from notionary.blocks.audio.audio_models import CreateAudioBlock
|
8
|
+
from notionary.blocks.base_block_element import BaseBlockElement
|
9
|
+
from notionary.blocks.file.file_element_models import (
|
10
|
+
ExternalFile,
|
11
|
+
FileBlock,
|
12
|
+
FileType,
|
13
|
+
FileUploadFile,
|
14
|
+
)
|
15
|
+
from notionary.blocks.mixins.captions import CaptionMixin
|
16
|
+
from notionary.blocks.mixins.file_upload.file_upload_mixin import FileUploadMixin
|
17
|
+
from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
|
18
|
+
from notionary.blocks.models import Block, BlockCreateResult, BlockType
|
19
|
+
from notionary.util.logging_mixin import LoggingMixin
|
20
|
+
|
21
|
+
|
22
|
+
class AudioElement(BaseBlockElement, FileUploadMixin, LoggingMixin, CaptionMixin):
|
23
|
+
r"""
|
24
|
+
Handles conversion between Markdown audio embeds and Notion audio blocks.
|
25
|
+
|
26
|
+
Supports both external URLs and local audio file uploads.
|
27
|
+
|
28
|
+
Markdown audio syntax:
|
29
|
+
- [audio](https://example.com/audio.mp3) - External URL
|
30
|
+
- [audio](./local/song.mp3) - Local audio file (will be uploaded)
|
31
|
+
- [audio](C:\Music\podcast.wav) - Absolute local path (will be uploaded)
|
32
|
+
- [audio](https://example.com/audio.mp3)(caption:Episode 1) - URL with caption
|
33
|
+
"""
|
34
|
+
|
35
|
+
AUDIO_PATTERN = re.compile(r"\[audio\]\(([^)]+)\)")
|
36
|
+
SUPPORTED_EXTENSIONS = {".mp3", ".wav", ".ogg", ".oga", ".m4a"}
|
37
|
+
|
38
|
+
@classmethod
|
39
|
+
def match_notion(cls, block: Block) -> bool:
|
40
|
+
"""Check if this element can handle the given Notion block."""
|
41
|
+
return block.type == BlockType.AUDIO
|
42
|
+
|
43
|
+
@classmethod
|
44
|
+
async def markdown_to_notion(cls, text: str) -> Optional[BlockCreateResult]:
|
45
|
+
"""Convert markdown audio embed to Notion audio block."""
|
46
|
+
# Extract the path/URL
|
47
|
+
path = cls._extract_audio_path(text.strip())
|
48
|
+
if not path:
|
49
|
+
return None
|
50
|
+
|
51
|
+
# Check if it's a local file path
|
52
|
+
if cls._is_local_file_path(path):
|
53
|
+
# Verify file exists and has supported extension
|
54
|
+
audio_path = Path(path)
|
55
|
+
if not audio_path.exists():
|
56
|
+
cls.logger.warning(f"Audio file not found: {path}")
|
57
|
+
return None
|
58
|
+
|
59
|
+
if audio_path.suffix.lower() not in cls.SUPPORTED_EXTENSIONS:
|
60
|
+
cls.logger.warning(f"Unsupported audio format: {audio_path.suffix}")
|
61
|
+
return None
|
62
|
+
|
63
|
+
cls.logger.info(f"Uploading local audio file: {path}")
|
64
|
+
|
65
|
+
# Upload the local audio file
|
66
|
+
file_upload_id = await cls._upload_local_file(path, "audio")
|
67
|
+
if not file_upload_id:
|
68
|
+
cls.logger.error(f"Failed to upload audio file: {path}")
|
69
|
+
return None
|
70
|
+
|
71
|
+
cls.logger.info(
|
72
|
+
f"Successfully uploaded audio file with ID: {file_upload_id}"
|
73
|
+
)
|
74
|
+
|
75
|
+
# Use mixin to extract caption (if present anywhere in text)
|
76
|
+
caption_text = cls.extract_caption(text.strip())
|
77
|
+
caption_rich_text = cls.build_caption_rich_text(caption_text or "")
|
78
|
+
|
79
|
+
audio_content = FileBlock(
|
80
|
+
type=FileType.FILE_UPLOAD,
|
81
|
+
file_upload=FileUploadFile(id=file_upload_id),
|
82
|
+
caption=caption_rich_text,
|
83
|
+
)
|
84
|
+
|
85
|
+
return CreateAudioBlock(audio=audio_content)
|
86
|
+
|
87
|
+
else:
|
88
|
+
# Handle external URL - accept any URL (validation happens at API level)
|
89
|
+
# Use mixin to extract caption (if present anywhere in text)
|
90
|
+
caption_text = cls.extract_caption(text.strip())
|
91
|
+
caption_rich_text = cls.build_caption_rich_text(caption_text or "")
|
92
|
+
|
93
|
+
audio_content = FileBlock(
|
94
|
+
type=FileType.EXTERNAL,
|
95
|
+
external=ExternalFile(url=path),
|
96
|
+
caption=caption_rich_text,
|
97
|
+
)
|
98
|
+
|
99
|
+
return CreateAudioBlock(audio=audio_content)
|
100
|
+
|
101
|
+
@classmethod
|
102
|
+
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
103
|
+
"""Convert Notion audio block to markdown audio embed."""
|
104
|
+
if block.type != BlockType.AUDIO or block.audio is None:
|
105
|
+
return None
|
106
|
+
|
107
|
+
audio = block.audio
|
108
|
+
url = None
|
109
|
+
|
110
|
+
# Handle both external URLs and uploaded files
|
111
|
+
if audio.type == FileType.EXTERNAL and audio.external is not None:
|
112
|
+
url = audio.external.url
|
113
|
+
elif audio.type == FileType.FILE_UPLOAD and audio.file_upload is not None:
|
114
|
+
url = audio.file_upload.url
|
115
|
+
|
116
|
+
if not url:
|
117
|
+
return None
|
118
|
+
|
119
|
+
result = f"[audio]({url})"
|
120
|
+
|
121
|
+
# Add caption if present
|
122
|
+
caption_markdown = await cls.format_caption_for_markdown(audio.caption or [])
|
123
|
+
if caption_markdown:
|
124
|
+
result += caption_markdown
|
125
|
+
|
126
|
+
return result
|
127
|
+
|
128
|
+
@classmethod
|
129
|
+
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
130
|
+
"""Get system prompt information for audio blocks."""
|
131
|
+
return BlockElementMarkdownInformation(
|
132
|
+
block_type=cls.__name__,
|
133
|
+
description="Audio blocks embed audio files from external URLs or local files with optional captions",
|
134
|
+
syntax_examples=[
|
135
|
+
"[audio](https://example.com/song.mp3)",
|
136
|
+
"[audio](./local/podcast.wav)",
|
137
|
+
"[audio](C:\\Music\\interview.mp3)",
|
138
|
+
"[audio](https://example.com/podcast.wav)(caption:Episode 1)",
|
139
|
+
"(caption:Background music)[audio](./song.mp3)",
|
140
|
+
"[audio](./interview.mp3)(caption:**Live** interview)",
|
141
|
+
],
|
142
|
+
usage_guidelines="Use for embedding audio files like music, podcasts, or sound effects. Supports both external URLs and local file uploads. Supports common audio formats (mp3, wav, ogg, m4a). Caption supports rich text formatting and is optional.",
|
143
|
+
)
|
144
|
+
|
145
|
+
@classmethod
|
146
|
+
def _is_likely_audio_url(cls, url: str) -> bool:
|
147
|
+
return any(url.lower().endswith(ext) for ext in cls.SUPPORTED_EXTENSIONS)
|
148
|
+
|
149
|
+
@classmethod
|
150
|
+
def _extract_audio_path(cls, text: str) -> Optional[str]:
|
151
|
+
"""Extract audio path/URL from text, handling caption patterns."""
|
152
|
+
clean_text = cls.remove_caption(text)
|
153
|
+
|
154
|
+
match = cls.AUDIO_PATTERN.search(clean_text)
|
155
|
+
if match:
|
156
|
+
return match.group(1).strip()
|
157
|
+
|
158
|
+
return None
|
@@ -1,30 +1,17 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
1
|
from typing import Optional
|
4
2
|
|
5
|
-
from
|
6
|
-
|
7
|
-
from notionary.markdown.markdown_node import MarkdownNode
|
3
|
+
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
8
4
|
from notionary.blocks.mixins.captions import CaptionMarkdownNodeMixin
|
9
5
|
|
10
6
|
|
11
|
-
class AudioMarkdownBlockParams(BaseModel):
|
12
|
-
url: str
|
13
|
-
caption: Optional[str] = None
|
14
|
-
|
15
|
-
|
16
7
|
class AudioMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
|
17
8
|
"""
|
9
|
+
Enhanced Audio node with Pydantic integration.
|
18
10
|
Programmatic interface for creating Notion-style audio blocks.
|
19
11
|
"""
|
20
12
|
|
21
|
-
|
22
|
-
|
23
|
-
self.caption = caption
|
24
|
-
|
25
|
-
@classmethod
|
26
|
-
def from_params(cls, params: AudioMarkdownBlockParams) -> AudioMarkdownNode:
|
27
|
-
return cls(url=params.url, caption=params.caption)
|
13
|
+
url: str
|
14
|
+
caption: Optional[str] = None
|
28
15
|
|
29
16
|
def to_markdown(self) -> str:
|
30
17
|
"""Return the Markdown representation.
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from notionary.blocks.bookmark.bookmark_element import BookmarkElement
|
2
2
|
from notionary.blocks.bookmark.bookmark_markdown_node import (
|
3
|
-
BookmarkMarkdownBlockParams,
|
4
3
|
BookmarkMarkdownNode,
|
5
4
|
)
|
6
5
|
from notionary.blocks.bookmark.bookmark_models import BookmarkBlock, CreateBookmarkBlock
|
@@ -10,5 +9,4 @@ __all__ = [
|
|
10
9
|
"BookmarkBlock",
|
11
10
|
"CreateBookmarkBlock",
|
12
11
|
"BookmarkMarkdownNode",
|
13
|
-
"BookmarkMarkdownBlockParams",
|
14
12
|
]
|
@@ -1,34 +1,18 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
1
|
from typing import Optional
|
4
2
|
|
5
|
-
from
|
6
|
-
|
7
|
-
from notionary.markdown.markdown_node import MarkdownNode
|
3
|
+
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
8
4
|
from notionary.blocks.mixins.captions import CaptionMarkdownNodeMixin
|
9
5
|
|
10
6
|
|
11
|
-
class BookmarkMarkdownBlockParams(BaseModel):
|
12
|
-
url: str
|
13
|
-
title: Optional[str] = None
|
14
|
-
caption: Optional[str] = None
|
15
|
-
|
16
|
-
|
17
7
|
class BookmarkMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
|
18
8
|
"""
|
9
|
+
Enhanced Bookmark node with Pydantic integration.
|
19
10
|
Programmatic interface for creating Notion-style bookmark Markdown blocks.
|
20
11
|
"""
|
21
12
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
self.url = url
|
26
|
-
self.title = title
|
27
|
-
self.caption = caption
|
28
|
-
|
29
|
-
@classmethod
|
30
|
-
def from_params(cls, params: BookmarkMarkdownBlockParams) -> BookmarkMarkdownNode:
|
31
|
-
return cls(url=params.url, title=params.title, caption=params.caption)
|
13
|
+
url: str
|
14
|
+
title: Optional[str] = None
|
15
|
+
caption: Optional[str] = None
|
32
16
|
|
33
17
|
def to_markdown(self) -> str:
|
34
18
|
"""Return the Markdown representation.
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from notionary.blocks.breadcrumbs.breadcrumb_element import BreadcrumbElement
|
2
2
|
from notionary.blocks.breadcrumbs.breadcrumb_markdown_node import (
|
3
|
-
BreadcrumbMarkdownBlockParams,
|
4
3
|
BreadcrumbMarkdownNode,
|
5
4
|
)
|
6
5
|
from notionary.blocks.breadcrumbs.breadcrumb_models import (
|
@@ -13,5 +12,4 @@ __all__ = [
|
|
13
12
|
"BreadcrumbBlock",
|
14
13
|
"CreateBreadcrumbBlock",
|
15
14
|
"BreadcrumbMarkdownNode",
|
16
|
-
"BreadcrumbMarkdownBlockParams",
|
17
15
|
]
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
2
|
+
|
3
|
+
|
4
|
+
class BreadcrumbMarkdownNode(MarkdownNode):
|
5
|
+
"""
|
6
|
+
Enhanced Breadcrumb node with Pydantic integration.
|
7
|
+
Programmatic interface for creating Markdown breadcrumb blocks.
|
8
|
+
Example:
|
9
|
+
[breadcrumb]
|
10
|
+
"""
|
11
|
+
|
12
|
+
def to_markdown(self) -> str:
|
13
|
+
return "[breadcrumb]"
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from notionary.blocks.bulleted_list.bulleted_list_element import BulletedListElement
|
2
2
|
from notionary.blocks.bulleted_list.bulleted_list_markdown_node import (
|
3
|
-
BulletedListMarkdownBlockParams,
|
4
3
|
BulletedListMarkdownNode,
|
5
4
|
)
|
6
5
|
from notionary.blocks.bulleted_list.bulleted_list_models import (
|
@@ -13,5 +12,4 @@ __all__ = [
|
|
13
12
|
"BulletedListItemBlock",
|
14
13
|
"CreateBulletedListItemBlock",
|
15
14
|
"BulletedListMarkdownNode",
|
16
|
-
"BulletedListMarkdownBlockParams",
|
17
15
|
]
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
2
|
+
|
3
|
+
|
4
|
+
class BulletedListMarkdownNode(MarkdownNode):
|
5
|
+
"""
|
6
|
+
Enhanced BulletedList node with Pydantic integration.
|
7
|
+
Programmatic interface for creating Markdown bulleted list items.
|
8
|
+
Example:
|
9
|
+
- First item
|
10
|
+
- Second item
|
11
|
+
- Third item
|
12
|
+
"""
|
13
|
+
|
14
|
+
texts: list[str]
|
15
|
+
|
16
|
+
def to_markdown(self) -> str:
|
17
|
+
result = []
|
18
|
+
for text in self.texts:
|
19
|
+
result.append(f"- {text}")
|
20
|
+
return "\n".join(result)
|
{notionary-0.2.23 → notionary-0.2.24}/notionary/blocks/bulleted_list/bulleted_list_models.py
RENAMED
@@ -10,7 +10,6 @@ from notionary.blocks.types import BlockColor
|
|
10
10
|
class BulletedListItemBlock(BaseModel):
|
11
11
|
rich_text: list[RichTextObject]
|
12
12
|
color: BlockColor = BlockColor.DEFAULT
|
13
|
-
children: list[Block] = Field(default_factory=list)
|
14
13
|
|
15
14
|
|
16
15
|
class CreateBulletedListItemBlock(BaseModel):
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from notionary.blocks.callout.callout_element import CalloutElement
|
2
2
|
from notionary.blocks.callout.callout_markdown_node import (
|
3
|
-
CalloutMarkdownBlockParams,
|
4
3
|
CalloutMarkdownNode,
|
5
4
|
)
|
6
5
|
from notionary.blocks.callout.callout_models import CalloutBlock, CreateCalloutBlock
|
@@ -10,5 +9,4 @@ __all__ = [
|
|
10
9
|
"CalloutBlock",
|
11
10
|
"CreateCalloutBlock",
|
12
11
|
"CalloutMarkdownNode",
|
13
|
-
"CalloutMarkdownBlockParams",
|
14
12
|
]
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
3
|
+
|
4
|
+
|
5
|
+
class CalloutMarkdownNode(MarkdownNode):
|
6
|
+
"""
|
7
|
+
Enhanced Callout node with Pydantic integration.
|
8
|
+
Programmatic interface for creating Notion-style callout Markdown blocks.
|
9
|
+
Example: [callout](This is important "⚠️")
|
10
|
+
"""
|
11
|
+
|
12
|
+
text: str
|
13
|
+
emoji: Optional[str] = None
|
14
|
+
|
15
|
+
def to_markdown(self) -> str:
|
16
|
+
if self.emoji and self.emoji != "💡":
|
17
|
+
return f'[callout]({self.text} "{self.emoji}")'
|
18
|
+
else:
|
19
|
+
return f"[callout]({self.text})"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from typing import Literal, Optional, Union
|
2
2
|
|
3
|
-
from pydantic import BaseModel, Field
|
3
|
+
from pydantic import BaseModel, Field, model_serializer
|
4
4
|
|
5
5
|
from notionary.blocks.file.file_element_models import FileBlock
|
6
6
|
from notionary.blocks.models import Block
|
@@ -23,10 +23,9 @@ IconObject = Union[EmojiIcon, FileIcon]
|
|
23
23
|
|
24
24
|
class CalloutBlock(BaseModel):
|
25
25
|
rich_text: list[RichTextObject]
|
26
|
-
icon: Optional[IconObject] = None
|
27
26
|
color: BlockColor = BlockColor.DEFAULT
|
28
|
-
|
29
|
-
|
27
|
+
icon: Optional[IconObject] = None
|
28
|
+
children: Optional[list[Block]] = None
|
30
29
|
|
31
30
|
class CreateCalloutBlock(BaseModel):
|
32
31
|
type: Literal["callout"] = "callout"
|
@@ -1,13 +1,11 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
1
|
from typing import Optional
|
4
2
|
|
5
|
-
from notionary.blocks.
|
6
|
-
from notionary.markdown.markdown_node import MarkdownNode
|
3
|
+
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
7
4
|
|
8
5
|
|
9
6
|
class CodeMarkdownNode(MarkdownNode):
|
10
7
|
"""
|
8
|
+
Enhanced Code node with Pydantic integration.
|
11
9
|
Programmatic interface for creating Notion-style Markdown code blocks.
|
12
10
|
Automatically handles indentation normalization for multiline strings.
|
13
11
|
|
@@ -17,21 +15,9 @@ class CodeMarkdownNode(MarkdownNode):
|
|
17
15
|
```
|
18
16
|
"""
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
language: Optional[str] = None,
|
24
|
-
caption: Optional[str] = None,
|
25
|
-
):
|
26
|
-
self.code = code
|
27
|
-
self.language = language or ""
|
28
|
-
self.caption = caption
|
29
|
-
|
30
|
-
@classmethod
|
31
|
-
def from_params(cls, params: CodeBlock) -> CodeMarkdownNode:
|
32
|
-
return cls(
|
33
|
-
code=params.rich_text, language=params.language, caption=params.caption
|
34
|
-
)
|
18
|
+
code: str
|
19
|
+
language: Optional[str] = None
|
20
|
+
caption: Optional[str] = None
|
35
21
|
|
36
22
|
def to_markdown(self) -> str:
|
37
23
|
lang = self.language or ""
|
@@ -1,11 +1,9 @@
|
|
1
1
|
from notionary.blocks.column.column_element import ColumnElement
|
2
2
|
from notionary.blocks.column.column_list_element import ColumnListElement
|
3
3
|
from notionary.blocks.column.column_list_markdown_node import (
|
4
|
-
ColumnListMarkdownBlockParams,
|
5
4
|
ColumnListMarkdownNode,
|
6
5
|
)
|
7
6
|
from notionary.blocks.column.column_markdown_node import (
|
8
|
-
ColumnMarkdownBlockParams,
|
9
7
|
ColumnMarkdownNode,
|
10
8
|
)
|
11
9
|
from notionary.blocks.column.column_models import (
|
@@ -23,7 +21,5 @@ __all__ = [
|
|
23
21
|
"ColumnListBlock",
|
24
22
|
"CreateColumnListBlock",
|
25
23
|
"ColumnMarkdownNode",
|
26
|
-
"ColumnMarkdownBlockParams",
|
27
24
|
"ColumnListMarkdownNode",
|
28
|
-
"ColumnListMarkdownBlockParams",
|
29
25
|
]
|
@@ -1,19 +1,10 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from pydantic import BaseModel
|
4
|
-
|
5
1
|
from notionary.blocks.column.column_markdown_node import ColumnMarkdownNode
|
6
|
-
from notionary.markdown.
|
7
|
-
from notionary.markdown.markdown_node import MarkdownNode
|
8
|
-
|
9
|
-
|
10
|
-
class ColumnListMarkdownBlockParams(BaseModel):
|
11
|
-
columns: list[list[MarkdownBlock]]
|
12
|
-
model_config = {"arbitrary_types_allowed": True}
|
2
|
+
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
13
3
|
|
14
4
|
|
15
5
|
class ColumnListMarkdownNode(MarkdownNode):
|
16
6
|
"""
|
7
|
+
Enhanced Column List node with Pydantic integration.
|
17
8
|
Programmatic interface for creating a Markdown column list container.
|
18
9
|
This represents the `::: columns` container that holds multiple columns.
|
19
10
|
|
@@ -31,14 +22,7 @@ class ColumnListMarkdownNode(MarkdownNode):
|
|
31
22
|
:::
|
32
23
|
"""
|
33
24
|
|
34
|
-
|
35
|
-
self.columns = columns
|
36
|
-
|
37
|
-
@classmethod
|
38
|
-
def from_params(
|
39
|
-
cls, params: ColumnListMarkdownBlockParams
|
40
|
-
) -> ColumnListMarkdownNode:
|
41
|
-
return cls(columns=params.columns)
|
25
|
+
columns: list[ColumnMarkdownNode] = []
|
42
26
|
|
43
27
|
def to_markdown(self) -> str:
|
44
28
|
if not self.columns:
|
@@ -1,20 +1,10 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
1
|
from typing import Optional
|
4
|
-
|
5
|
-
from pydantic import BaseModel
|
6
|
-
|
7
|
-
from notionary.markdown.markdown_node import MarkdownNode
|
8
|
-
|
9
|
-
|
10
|
-
class ColumnMarkdownBlockParams(BaseModel):
|
11
|
-
children: list[MarkdownNode]
|
12
|
-
width_ratio: Optional[float] = None
|
13
|
-
model_config = {"arbitrary_types_allowed": True}
|
2
|
+
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
14
3
|
|
15
4
|
|
16
5
|
class ColumnMarkdownNode(MarkdownNode):
|
17
6
|
"""
|
7
|
+
Enhanced Column node with Pydantic integration.
|
18
8
|
Programmatic interface for creating a single Markdown column block
|
19
9
|
with nested content and optional width ratio.
|
20
10
|
|
@@ -32,15 +22,8 @@ class ColumnMarkdownNode(MarkdownNode):
|
|
32
22
|
:::
|
33
23
|
"""
|
34
24
|
|
35
|
-
|
36
|
-
|
37
|
-
):
|
38
|
-
self.children = children
|
39
|
-
self.width_ratio = width_ratio
|
40
|
-
|
41
|
-
@classmethod
|
42
|
-
def from_params(cls, params: ColumnMarkdownBlockParams) -> ColumnMarkdownNode:
|
43
|
-
return cls(children=params.children, width_ratio=params.width_ratio)
|
25
|
+
children: list[MarkdownNode] = []
|
26
|
+
width_ratio: Optional[float] = None
|
44
27
|
|
45
28
|
def to_markdown(self) -> str:
|
46
29
|
# Start tag with optional width ratio
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from notionary.blocks.divider.divider_element import DividerElement
|
2
2
|
from notionary.blocks.divider.divider_markdown_node import (
|
3
|
-
DividerMarkdownBlockParams,
|
4
3
|
DividerMarkdownNode,
|
5
4
|
)
|
6
5
|
from notionary.blocks.divider.divider_models import CreateDividerBlock, DividerBlock
|
@@ -10,5 +9,4 @@ __all__ = [
|
|
10
9
|
"DividerBlock",
|
11
10
|
"CreateDividerBlock",
|
12
11
|
"DividerMarkdownNode",
|
13
|
-
"DividerMarkdownBlockParams",
|
14
12
|
]
|
@@ -0,0 +1,11 @@
|
|
1
|
+
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
2
|
+
|
3
|
+
|
4
|
+
class DividerMarkdownNode(MarkdownNode):
|
5
|
+
"""
|
6
|
+
Enhanced Divider node with Pydantic integration.
|
7
|
+
Programmatic interface for creating Markdown divider lines (---).
|
8
|
+
"""
|
9
|
+
|
10
|
+
def to_markdown(self) -> str:
|
11
|
+
return "---"
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from notionary.blocks.embed.embed_element import EmbedElement
|
2
2
|
from notionary.blocks.embed.embed_markdown_node import (
|
3
|
-
EmbedMarkdownBlockParams,
|
4
3
|
EmbedMarkdownNode,
|
5
4
|
)
|
6
5
|
from notionary.blocks.embed.embed_models import CreateEmbedBlock, EmbedBlock
|
@@ -10,5 +9,4 @@ __all__ = [
|
|
10
9
|
"EmbedBlock",
|
11
10
|
"CreateEmbedBlock",
|
12
11
|
"EmbedMarkdownNode",
|
13
|
-
"EmbedMarkdownBlockParams",
|
14
12
|
]
|