notionary 0.2.28__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.2.28 → notionary-0.3.0}/PKG-INFO +27 -101
- {notionary-0.2.28 → notionary-0.3.0}/README.md +26 -100
- notionary-0.3.0/notionary/blocks/__init__.py +5 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/client.py +6 -4
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/enums.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/markdown_rich_text_converter.py +14 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/models.py +14 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/name_id_resolver/__init__.py +2 -0
- notionary-0.3.0/notionary/blocks/rich_text/name_id_resolver/data_source.py +32 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/rich_text_markdown_converter.py +12 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/rich_text_patterns.py +3 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/schemas.py +42 -10
- notionary-0.3.0/notionary/comments/__init__.py +5 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/comments/client.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/comments/factory.py +4 -6
- {notionary-0.2.28 → notionary-0.3.0}/notionary/data_source/http/data_source_instance_client.py +14 -4
- notionary-0.2.28/notionary/data_source/properties/models.py → notionary-0.3.0/notionary/data_source/properties/schemas.py +4 -8
- {notionary-0.2.28 → notionary-0.3.0}/notionary/data_source/query/builder.py +29 -10
- {notionary-0.2.28 → notionary-0.3.0}/notionary/data_source/query/schema.py +8 -10
- {notionary-0.2.28 → notionary-0.3.0}/notionary/data_source/query/validator.py +11 -11
- 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.2.28 → notionary-0.3.0}/notionary/data_source/schemas.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/data_source/service.py +33 -9
- {notionary-0.2.28 → notionary-0.3.0}/notionary/database/service.py +1 -2
- {notionary-0.2.28 → notionary-0.3.0}/notionary/exceptions/__init__.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/exceptions/search.py +24 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/http/client.py +8 -9
- {notionary-0.2.28 → notionary-0.3.0}/notionary/http/models.py +5 -4
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/factory.py +8 -3
- notionary-0.3.0/notionary/page/content/markdown/builder.py +226 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/__init__.py +0 -2
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/audio.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/base.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/bookmark.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/breadcrumb.py +1 -1
- 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.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/code.py +3 -5
- 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.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/divider.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/embed.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/equation.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/file.py +1 -1
- notionary-0.3.0/notionary/page/content/markdown/nodes/heading.py +36 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/image.py +1 -1
- notionary-0.3.0/notionary/page/content/markdown/nodes/mixins/__init__.py +5 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/mixins/caption.py +1 -1
- notionary-0.3.0/notionary/page/content/markdown/nodes/numbered_list.py +38 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/paragraph.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/pdf.py +1 -1
- notionary-0.3.0/notionary/page/content/markdown/nodes/quote.py +27 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/space.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/table.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/table_of_contents.py +1 -1
- 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.2.28 → notionary-0.3.0}/notionary/page/content/markdown/nodes/video.py +1 -1
- notionary-0.3.0/notionary/page/content/parser/context.py +126 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/factory.py +1 -10
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/__init__.py +0 -2
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/audio.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/base.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/bookmark.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/breadcrumb.py +1 -1
- 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.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/caption.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/code.py +5 -5
- 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.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/divider.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/embed.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/equation.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/file.py +1 -1
- notionary-0.3.0/notionary/page/content/parser/parsers/heading.py +115 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/image.py +1 -1
- notionary-0.3.0/notionary/page/content/parser/parsers/numbered_list.py +89 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/paragraph.py +3 -2
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/pdf.py +1 -1
- notionary-0.3.0/notionary/page/content/parser/parsers/quote.py +125 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/space.py +14 -8
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/table.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/table_of_contents.py +1 -1
- 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.2.28 → notionary-0.3.0}/notionary/page/content/parser/parsers/video.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/post_processing/handlers/rich_text_length.py +6 -4
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +43 -22
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/pre_processsing/handlers/__init__.py +2 -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.2.28 → notionary-0.3.0}/notionary/page/content/parser/pre_processsing/handlers/whitespace.py +12 -7
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/service.py +9 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/context.py +5 -2
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/factory.py +2 -11
- 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.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/__init__.py +0 -2
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/base.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/bulleted_list.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/callout.py +6 -21
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/captioned_block.py +1 -1
- 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/heading.py +95 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/numbered_list.py +6 -5
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/quote.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/todo.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/toggle.py +6 -7
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/service.py +4 -1
- 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.2.28 → notionary-0.3.0}/notionary/page/content/syntax/models.py +0 -2
- notionary-0.2.28/notionary/page/content/syntax/service.py → notionary-0.3.0/notionary/page/content/syntax/registry.py +31 -91
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/properties/client.py +1 -1
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/properties/models.py +3 -2
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/properties/service.py +4 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/service.py +5 -2
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/models/cover.py +1 -1
- notionary-0.3.0/notionary/shared/typings.py +3 -0
- notionary-0.3.0/notionary/user/base.py +138 -0
- notionary-0.3.0/notionary/user/factory.py +0 -0
- notionary-0.3.0/notionary/utils/decorators.py +122 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/utils/fuzzy.py +18 -6
- 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/workspace/__init__.py +4 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/workspace/client.py +2 -2
- notionary-0.3.0/notionary/workspace/query/__init__.py +3 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/workspace/query/models.py +4 -3
- {notionary-0.2.28 → notionary-0.3.0}/notionary/workspace/query/service.py +29 -22
- {notionary-0.2.28 → notionary-0.3.0}/pyproject.toml +1 -1
- notionary-0.2.28/notionary/page/content/markdown/builder.py +0 -304
- notionary-0.2.28/notionary/page/content/markdown/nodes/bulleted_list.py +0 -18
- notionary-0.2.28/notionary/page/content/markdown/nodes/callout.py +0 -32
- notionary-0.2.28/notionary/page/content/markdown/nodes/columns.py +0 -51
- notionary-0.2.28/notionary/page/content/markdown/nodes/heading.py +0 -16
- notionary-0.2.28/notionary/page/content/markdown/nodes/numbered_list.py +0 -15
- notionary-0.2.28/notionary/page/content/markdown/nodes/quote.py +0 -15
- notionary-0.2.28/notionary/page/content/markdown/nodes/todo.py +0 -22
- notionary-0.2.28/notionary/page/content/markdown/nodes/toggle.py +0 -28
- notionary-0.2.28/notionary/page/content/markdown/nodes/toggleable_heading.py +0 -35
- notionary-0.2.28/notionary/page/content/parser/context.py +0 -49
- notionary-0.2.28/notionary/page/content/parser/parsers/bulleted_list.py +0 -41
- notionary-0.2.28/notionary/page/content/parser/parsers/callout.py +0 -129
- notionary-0.2.28/notionary/page/content/parser/parsers/column.py +0 -117
- notionary-0.2.28/notionary/page/content/parser/parsers/column_list.py +0 -81
- notionary-0.2.28/notionary/page/content/parser/parsers/heading.py +0 -58
- notionary-0.2.28/notionary/page/content/parser/parsers/numbered_list.py +0 -45
- notionary-0.2.28/notionary/page/content/parser/parsers/quote.py +0 -65
- notionary-0.2.28/notionary/page/content/parser/parsers/todo.py +0 -58
- notionary-0.2.28/notionary/page/content/parser/parsers/toggle.py +0 -127
- notionary-0.2.28/notionary/page/content/parser/parsers/toggleable_heading.py +0 -150
- notionary-0.2.28/notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +0 -80
- notionary-0.2.28/notionary/page/content/renderer/post_processing/handlers/__init__.py +0 -5
- notionary-0.2.28/notionary/page/content/renderer/post_processing/handlers/numbered_list_placeholdere.py +0 -62
- notionary-0.2.28/notionary/page/content/renderer/renderers/column.py +0 -44
- notionary-0.2.28/notionary/page/content/renderer/renderers/column_list.py +0 -31
- notionary-0.2.28/notionary/page/content/renderer/renderers/heading.py +0 -69
- notionary-0.2.28/notionary/page/content/renderer/renderers/toggleable_heading.py +0 -78
- notionary-0.2.28/notionary/user/base.py +0 -89
- notionary-0.2.28/notionary/utils/async_retry.py +0 -39
- notionary-0.2.28/notionary/utils/mixins/logging.py +0 -47
- notionary-0.2.28/notionary/utils/pagination.py +0 -50
- notionary-0.2.28/notionary/utils/singleton.py +0 -13
- notionary-0.2.28/notionary/workspace/__init__.py +0 -3
- {notionary-0.2.28 → notionary-0.3.0}/.gitignore +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/LICENSE +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/__init__.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/name_id_resolver/database.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/name_id_resolver/page.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/name_id_resolver/person.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/name_id_resolver/port.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/comments/models.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/comments/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/comments/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/data_source/http/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/data_source/query/resolver.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/database/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/database/database_metadata_update_client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/database/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/exceptions/api.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/exceptions/base.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/exceptions/block_parsing.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/exceptions/data_source/__init__.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/exceptions/data_source/builder.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/exceptions/data_source/properties.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/exceptions/properties.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/file_upload/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/file_upload/models.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/file_upload/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/blocks/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/markdown/__init__.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/post_processing/handlers/__init__.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/post_processing/port.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/post_processing/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/pre_processsing/handlers/port.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/parser/pre_processsing/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/post_processing/port.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/post_processing/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/audio.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/bookmark.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/breadcrumb.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/code.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/divider.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/embed.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/equation.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/fallback.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/file.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/image.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/paragraph.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/pdf.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/table.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/table_of_contents.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/table_row.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/renderers/video.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/content/renderer/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/page_context.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/page_http_client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/page_metadata_update_client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/properties/factory.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/page/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/entity/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/entity/dto_parsers.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/entity/entity_metadata_update_client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/entity/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/entity/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/models/file.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/models/icon.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/models/parent.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/shared/properties/type.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/user/__init__.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/user/bot.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/user/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/user/person.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/user/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/user/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/utils/date.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/utils/uuid_utils.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/workspace/query/builder.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/workspace/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.0}/notionary/workspace/service.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: notionary
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Python library for programmatic Notion workspace management - databases, pages, and content with advanced Markdown support
|
|
5
5
|
Project-URL: Homepage, https://github.com/mathisarends/notionary
|
|
6
6
|
Author-email: Mathis Arends <mathisarends27@gmail.com>
|
|
@@ -61,17 +61,9 @@ export NOTION_SECRET=your_integration_key
|
|
|
61
61
|
|
|
62
62
|
## See It in Action
|
|
63
63
|
|
|
64
|
-
### Creating Rich Database Entries
|
|
65
|
-
|
|
66
64
|
https://github.com/user-attachments/assets/da8b4691-bee4-4b0f-801e-dccacb630398
|
|
67
65
|
|
|
68
|
-
_Create
|
|
69
|
-
|
|
70
|
-
### Local File Uploads (Videos & Images)
|
|
71
|
-
|
|
72
|
-
https://github.com/user-attachments/assets/a079ec01-bb56-4c65-8260-7b1fca42ac68
|
|
73
|
-
|
|
74
|
-
_Upload videos and images using simple markdown syntax - files are automatically uploaded to Notion_
|
|
66
|
+
_Create rich database entries with properties, content, and beautiful formatting_
|
|
75
67
|
|
|
76
68
|
---
|
|
77
69
|
|
|
@@ -80,50 +72,30 @@ _Upload videos and images using simple markdown syntax - files are automatically
|
|
|
80
72
|
### Find → Create → Update Flow
|
|
81
73
|
|
|
82
74
|
```python
|
|
83
|
-
import
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
.h2("Project Status")
|
|
108
|
-
.callout("Milestone reached!", "🎉")
|
|
109
|
-
.columns(
|
|
110
|
-
lambda col: col.h3("Completed").bulleted_list([
|
|
111
|
-
"API design", "Database setup", "Authentication"
|
|
112
|
-
]),
|
|
113
|
-
lambda col: col.h3("In Progress").bulleted_list([
|
|
114
|
-
"Frontend UI", "Testing", "Documentation"
|
|
115
|
-
]),
|
|
116
|
-
width_ratios=[0.6, 0.4]
|
|
117
|
-
)
|
|
118
|
-
.toggle("Budget Details", lambda t: t
|
|
119
|
-
.table(["Item", "Cost", "Status"], [
|
|
120
|
-
["Development", "$15,000", "Paid"],
|
|
121
|
-
["Design", "$8,000", "Pending"]
|
|
122
|
-
])
|
|
123
|
-
)
|
|
124
|
-
))
|
|
125
|
-
|
|
126
|
-
asyncio.run(main())
|
|
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)
|
|
127
99
|
```
|
|
128
100
|
|
|
129
101
|
### Complete Block Support
|
|
@@ -132,36 +104,13 @@ Every Notion block type with extended syntax:
|
|
|
132
104
|
|
|
133
105
|
| Block Type | Markdown Syntax | Use Case |
|
|
134
106
|
| ------------- | -------------------------------------------- | ---------------------------- |
|
|
135
|
-
| **Callouts** | `[callout](Text "🔥")` | Highlighting key information |
|
|
136
107
|
| **Toggles** | `+++ Title\nContent\n+++` | Collapsible sections |
|
|
137
108
|
| **Columns** | `::: columns\n::: column\nContent\n:::\n:::` | Side-by-side layouts |
|
|
138
109
|
| **Tables** | Standard markdown tables | Structured data |
|
|
139
110
|
| **Media** | `[video](./file.mp4)(caption:Description)` | Auto-uploading files |
|
|
140
111
|
| **Code** | Standard code fences with captions | Code snippets |
|
|
141
112
|
| **Equations** | `$LaTeX$` | Mathematical expressions |
|
|
142
|
-
| **TOC** | `[toc]
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
## What You Can Build 💡
|
|
147
|
-
|
|
148
|
-
### **AI Content Systems**
|
|
149
|
-
|
|
150
|
-
- **Report Generation**: AI agents that create structured reports, documentation, and analysis
|
|
151
|
-
- **Content Pipelines**: Automated workflows that process data and generate Notion pages
|
|
152
|
-
- **Knowledge Management**: AI-powered documentation systems with smart categorization
|
|
153
|
-
|
|
154
|
-
### **Workflow Automation**
|
|
155
|
-
|
|
156
|
-
- **Project Management**: Sync project status, update timelines, generate progress reports
|
|
157
|
-
- **Data Integration**: Connect external APIs and databases to Notion workspaces
|
|
158
|
-
- **Template Systems**: Dynamic page generation from templates and data sources
|
|
159
|
-
|
|
160
|
-
### **Content Management**
|
|
161
|
-
|
|
162
|
-
- **Bulk Operations**: Mass page updates, content migration, and database management
|
|
163
|
-
- **Media Handling**: Automated image/video uploads with proper organization
|
|
164
|
-
- **Cross-Platform**: Sync content between Notion and other platforms
|
|
113
|
+
| **TOC** | `[toc]` | Auto-generated navigation |
|
|
165
114
|
|
|
166
115
|
---
|
|
167
116
|
|
|
@@ -222,29 +171,6 @@ Every Notion block type with extended syntax:
|
|
|
222
171
|
|
|
223
172
|
[**mathisarends.github.io/notionary**](https://mathisarends.github.io/notionary/) - Complete API reference, guides, and tutorials
|
|
224
173
|
|
|
225
|
-
### Quick Links
|
|
226
|
-
|
|
227
|
-
- [**Getting Started**](https://mathisarends.github.io/notionary/get-started/) - Setup and first steps
|
|
228
|
-
- [**Page Management**](https://mathisarends.github.io/notionary/page/) - Content and properties
|
|
229
|
-
- [**Database Operations**](https://mathisarends.github.io/notionary/database/) - Queries and management
|
|
230
|
-
- [**Block Types Reference**](https://mathisarends.github.io/notionary/blocks/) - Complete syntax guide
|
|
231
|
-
|
|
232
|
-
### Hands-On Examples
|
|
233
|
-
|
|
234
|
-
**Core Functionality:**
|
|
235
|
-
|
|
236
|
-
- [Page Management](examples/page_example.py) - Create, update, and manage pages
|
|
237
|
-
- [Database Operations](examples/database.py) - Connect and query databases
|
|
238
|
-
- [Workspace Discovery](examples/workspace_discovery.py) - Explore your workspace
|
|
239
|
-
|
|
240
|
-
**Extended Markdown:**
|
|
241
|
-
|
|
242
|
-
- [Basic Formatting](examples/markdown/basic.py) - Text, lists, and links
|
|
243
|
-
- [Callouts & Highlights](examples/markdown/callout.py) - Information boxes
|
|
244
|
-
- [Toggle Sections](examples/markdown/toggle.py) - Collapsible content
|
|
245
|
-
- [Multi-Column Layouts](examples/markdown/columns.py) - Side-by-side design
|
|
246
|
-
- [Tables & Data](examples/markdown/table.py) - Structured presentations
|
|
247
|
-
|
|
248
174
|
---
|
|
249
175
|
|
|
250
176
|
## Contributing
|
|
@@ -46,17 +46,9 @@ export NOTION_SECRET=your_integration_key
|
|
|
46
46
|
|
|
47
47
|
## See It in Action
|
|
48
48
|
|
|
49
|
-
### Creating Rich Database Entries
|
|
50
|
-
|
|
51
49
|
https://github.com/user-attachments/assets/da8b4691-bee4-4b0f-801e-dccacb630398
|
|
52
50
|
|
|
53
|
-
_Create
|
|
54
|
-
|
|
55
|
-
### Local File Uploads (Videos & Images)
|
|
56
|
-
|
|
57
|
-
https://github.com/user-attachments/assets/a079ec01-bb56-4c65-8260-7b1fca42ac68
|
|
58
|
-
|
|
59
|
-
_Upload videos and images using simple markdown syntax - files are automatically uploaded to Notion_
|
|
51
|
+
_Create rich database entries with properties, content, and beautiful formatting_
|
|
60
52
|
|
|
61
53
|
---
|
|
62
54
|
|
|
@@ -65,50 +57,30 @@ _Upload videos and images using simple markdown syntax - files are automatically
|
|
|
65
57
|
### Find → Create → Update Flow
|
|
66
58
|
|
|
67
59
|
```python
|
|
68
|
-
import
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.h2("Project Status")
|
|
93
|
-
.callout("Milestone reached!", "🎉")
|
|
94
|
-
.columns(
|
|
95
|
-
lambda col: col.h3("Completed").bulleted_list([
|
|
96
|
-
"API design", "Database setup", "Authentication"
|
|
97
|
-
]),
|
|
98
|
-
lambda col: col.h3("In Progress").bulleted_list([
|
|
99
|
-
"Frontend UI", "Testing", "Documentation"
|
|
100
|
-
]),
|
|
101
|
-
width_ratios=[0.6, 0.4]
|
|
102
|
-
)
|
|
103
|
-
.toggle("Budget Details", lambda t: t
|
|
104
|
-
.table(["Item", "Cost", "Status"], [
|
|
105
|
-
["Development", "$15,000", "Paid"],
|
|
106
|
-
["Design", "$8,000", "Pending"]
|
|
107
|
-
])
|
|
108
|
-
)
|
|
109
|
-
))
|
|
110
|
-
|
|
111
|
-
asyncio.run(main())
|
|
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)
|
|
112
84
|
```
|
|
113
85
|
|
|
114
86
|
### Complete Block Support
|
|
@@ -117,36 +89,13 @@ Every Notion block type with extended syntax:
|
|
|
117
89
|
|
|
118
90
|
| Block Type | Markdown Syntax | Use Case |
|
|
119
91
|
| ------------- | -------------------------------------------- | ---------------------------- |
|
|
120
|
-
| **Callouts** | `[callout](Text "🔥")` | Highlighting key information |
|
|
121
92
|
| **Toggles** | `+++ Title\nContent\n+++` | Collapsible sections |
|
|
122
93
|
| **Columns** | `::: columns\n::: column\nContent\n:::\n:::` | Side-by-side layouts |
|
|
123
94
|
| **Tables** | Standard markdown tables | Structured data |
|
|
124
95
|
| **Media** | `[video](./file.mp4)(caption:Description)` | Auto-uploading files |
|
|
125
96
|
| **Code** | Standard code fences with captions | Code snippets |
|
|
126
97
|
| **Equations** | `$LaTeX$` | Mathematical expressions |
|
|
127
|
-
| **TOC** | `[toc]
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## What You Can Build 💡
|
|
132
|
-
|
|
133
|
-
### **AI Content Systems**
|
|
134
|
-
|
|
135
|
-
- **Report Generation**: AI agents that create structured reports, documentation, and analysis
|
|
136
|
-
- **Content Pipelines**: Automated workflows that process data and generate Notion pages
|
|
137
|
-
- **Knowledge Management**: AI-powered documentation systems with smart categorization
|
|
138
|
-
|
|
139
|
-
### **Workflow Automation**
|
|
140
|
-
|
|
141
|
-
- **Project Management**: Sync project status, update timelines, generate progress reports
|
|
142
|
-
- **Data Integration**: Connect external APIs and databases to Notion workspaces
|
|
143
|
-
- **Template Systems**: Dynamic page generation from templates and data sources
|
|
144
|
-
|
|
145
|
-
### **Content Management**
|
|
146
|
-
|
|
147
|
-
- **Bulk Operations**: Mass page updates, content migration, and database management
|
|
148
|
-
- **Media Handling**: Automated image/video uploads with proper organization
|
|
149
|
-
- **Cross-Platform**: Sync content between Notion and other platforms
|
|
98
|
+
| **TOC** | `[toc]` | Auto-generated navigation |
|
|
150
99
|
|
|
151
100
|
---
|
|
152
101
|
|
|
@@ -207,29 +156,6 @@ Every Notion block type with extended syntax:
|
|
|
207
156
|
|
|
208
157
|
[**mathisarends.github.io/notionary**](https://mathisarends.github.io/notionary/) - Complete API reference, guides, and tutorials
|
|
209
158
|
|
|
210
|
-
### Quick Links
|
|
211
|
-
|
|
212
|
-
- [**Getting Started**](https://mathisarends.github.io/notionary/get-started/) - Setup and first steps
|
|
213
|
-
- [**Page Management**](https://mathisarends.github.io/notionary/page/) - Content and properties
|
|
214
|
-
- [**Database Operations**](https://mathisarends.github.io/notionary/database/) - Queries and management
|
|
215
|
-
- [**Block Types Reference**](https://mathisarends.github.io/notionary/blocks/) - Complete syntax guide
|
|
216
|
-
|
|
217
|
-
### Hands-On Examples
|
|
218
|
-
|
|
219
|
-
**Core Functionality:**
|
|
220
|
-
|
|
221
|
-
- [Page Management](examples/page_example.py) - Create, update, and manage pages
|
|
222
|
-
- [Database Operations](examples/database.py) - Connect and query databases
|
|
223
|
-
- [Workspace Discovery](examples/workspace_discovery.py) - Explore your workspace
|
|
224
|
-
|
|
225
|
-
**Extended Markdown:**
|
|
226
|
-
|
|
227
|
-
- [Basic Formatting](examples/markdown/basic.py) - Text, lists, and links
|
|
228
|
-
- [Callouts & Highlights](examples/markdown/callout.py) - Information boxes
|
|
229
|
-
- [Toggle Sections](examples/markdown/toggle.py) - Collapsible content
|
|
230
|
-
- [Multi-Column Layouts](examples/markdown/columns.py) - Side-by-side design
|
|
231
|
-
- [Tables & Data](examples/markdown/table.py) - Structured presentations
|
|
232
|
-
|
|
233
159
|
---
|
|
234
160
|
|
|
235
161
|
## Contributing
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
|
|
3
1
|
from notionary.blocks.schemas import Block, BlockChildrenResponse, BlockCreatePayload
|
|
4
2
|
from notionary.http.client import NotionHttpClient
|
|
3
|
+
from notionary.shared.typings import JsonDict
|
|
4
|
+
from notionary.utils.decorators import time_execution_async
|
|
5
5
|
from notionary.utils.pagination import paginate_notion_api
|
|
6
6
|
|
|
7
7
|
|
|
@@ -16,6 +16,7 @@ class NotionBlockHttpClient(NotionHttpClient):
|
|
|
16
16
|
self.logger.debug("Deleting block: %s", block_id)
|
|
17
17
|
await self.delete(f"blocks/{block_id}")
|
|
18
18
|
|
|
19
|
+
@time_execution_async()
|
|
19
20
|
async def get_block_tree(self, parent_block_id: str) -> list[Block]:
|
|
20
21
|
blocks_at_this_level = await self.get_all_block_children(parent_block_id)
|
|
21
22
|
|
|
@@ -26,6 +27,7 @@ class NotionBlockHttpClient(NotionHttpClient):
|
|
|
26
27
|
|
|
27
28
|
return blocks_at_this_level
|
|
28
29
|
|
|
30
|
+
@time_execution_async()
|
|
29
31
|
async def get_all_block_children(self, parent_block_id: str) -> list[Block]:
|
|
30
32
|
self.logger.debug("Retrieving all children for block: %s", parent_block_id)
|
|
31
33
|
|
|
@@ -73,11 +75,11 @@ class NotionBlockHttpClient(NotionHttpClient):
|
|
|
73
75
|
batches.append(batch)
|
|
74
76
|
return batches
|
|
75
77
|
|
|
76
|
-
def _serialize_blocks(self, blocks: list[BlockCreatePayload]) -> list[
|
|
78
|
+
def _serialize_blocks(self, blocks: list[BlockCreatePayload]) -> list[JsonDict]:
|
|
77
79
|
return [block.model_dump(exclude_none=True) for block in blocks]
|
|
78
80
|
|
|
79
81
|
async def _send_append_request(
|
|
80
|
-
self, block_id: str, children: list[
|
|
82
|
+
self, block_id: str, children: list[JsonDict], after_block_id: str | None = None
|
|
81
83
|
) -> BlockChildrenResponse:
|
|
82
84
|
payload = {"children": children}
|
|
83
85
|
if after_block_id:
|
{notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/markdown_rich_text_converter.py
RENAMED
|
@@ -7,6 +7,7 @@ from typing import ClassVar
|
|
|
7
7
|
from notionary.blocks.rich_text.models import MentionType, RichText, RichTextType, TextAnnotations
|
|
8
8
|
from notionary.blocks.rich_text.name_id_resolver import (
|
|
9
9
|
DatabaseNameIdResolver,
|
|
10
|
+
DataSourceNameIdResolver,
|
|
10
11
|
NameIdResolver,
|
|
11
12
|
PageNameIdResolver,
|
|
12
13
|
PersonNameIdResolver,
|
|
@@ -44,10 +45,12 @@ class MarkdownRichTextConverter:
|
|
|
44
45
|
*,
|
|
45
46
|
page_resolver: NameIdResolver | None = None,
|
|
46
47
|
database_resolver: NameIdResolver | None = None,
|
|
48
|
+
data_source_resolver: NameIdResolver | None = None,
|
|
47
49
|
person_resolver: NameIdResolver | None = None,
|
|
48
50
|
):
|
|
49
51
|
self.page_resolver = page_resolver or PageNameIdResolver()
|
|
50
52
|
self.database_resolver = database_resolver or DatabaseNameIdResolver()
|
|
53
|
+
self.data_source_resolver = data_source_resolver or DataSourceNameIdResolver()
|
|
51
54
|
self.person_resolver = person_resolver or PersonNameIdResolver()
|
|
52
55
|
self.format_handlers = self._setup_format_handlers()
|
|
53
56
|
|
|
@@ -64,6 +67,7 @@ class MarkdownRichTextConverter:
|
|
|
64
67
|
PatternHandler(RichTextPatterns.COLOR, self._handle_color_pattern),
|
|
65
68
|
PatternHandler(RichTextPatterns.PAGE_MENTION, self._handle_page_mention_pattern),
|
|
66
69
|
PatternHandler(RichTextPatterns.DATABASE_MENTION, self._handle_database_mention_pattern),
|
|
70
|
+
PatternHandler(RichTextPatterns.DATASOURCE_MENTION, self._handle_data_source_mention_pattern),
|
|
67
71
|
PatternHandler(RichTextPatterns.USER_MENTION, self._handle_user_mention_pattern),
|
|
68
72
|
]
|
|
69
73
|
|
|
@@ -119,6 +123,7 @@ class MarkdownRichTextConverter:
|
|
|
119
123
|
async_handlers = {
|
|
120
124
|
self._handle_page_mention_pattern,
|
|
121
125
|
self._handle_database_mention_pattern,
|
|
126
|
+
self._handle_data_source_mention_pattern,
|
|
122
127
|
self._handle_color_pattern, # Color pattern needs async for recursive parsing
|
|
123
128
|
self._handle_user_mention_pattern,
|
|
124
129
|
}
|
|
@@ -210,6 +215,15 @@ class MarkdownRichTextConverter:
|
|
|
210
215
|
mention_type=MentionType.DATABASE,
|
|
211
216
|
)
|
|
212
217
|
|
|
218
|
+
async def _handle_data_source_mention_pattern(self, match: Match) -> RichText:
|
|
219
|
+
identifier = match.group(1)
|
|
220
|
+
return await self._create_mention_or_fallback(
|
|
221
|
+
identifier=identifier,
|
|
222
|
+
resolve_func=self.data_source_resolver.resolve_name_to_id,
|
|
223
|
+
create_mention_func=RichText.mention_data_source,
|
|
224
|
+
mention_type=MentionType.DATASOURCE,
|
|
225
|
+
)
|
|
226
|
+
|
|
213
227
|
async def _handle_user_mention_pattern(self, match: Match) -> RichText:
|
|
214
228
|
identifier = match.group(1)
|
|
215
229
|
return await self._create_mention_or_fallback(
|
|
@@ -16,6 +16,7 @@ class MentionType(StrEnum):
|
|
|
16
16
|
USER = "user"
|
|
17
17
|
PAGE = "page"
|
|
18
18
|
DATABASE = "database"
|
|
19
|
+
DATASOURCE = "data_source"
|
|
19
20
|
DATE = "date"
|
|
20
21
|
LINK_PREVIEW = "link_preview"
|
|
21
22
|
TEMPLATE_MENTION = "template_mention"
|
|
@@ -60,6 +61,10 @@ class MentionDatabaseRef(BaseModel):
|
|
|
60
61
|
id: str
|
|
61
62
|
|
|
62
63
|
|
|
64
|
+
class MentionDataSourceRef(BaseModel):
|
|
65
|
+
id: str
|
|
66
|
+
|
|
67
|
+
|
|
63
68
|
class MentionLinkPreview(BaseModel):
|
|
64
69
|
url: str
|
|
65
70
|
|
|
@@ -81,6 +86,7 @@ class MentionObject(BaseModel):
|
|
|
81
86
|
user: MentionUserRef | None = None
|
|
82
87
|
page: MentionPageRef | None = None
|
|
83
88
|
database: MentionDatabaseRef | None = None
|
|
89
|
+
data_source: MentionDataSourceRef | None = None
|
|
84
90
|
date: MentionDate | None = None
|
|
85
91
|
link_preview: MentionLinkPreview | None = None
|
|
86
92
|
template_mention: MentionTemplateMention | None = None
|
|
@@ -154,6 +160,14 @@ class RichText(BaseModel):
|
|
|
154
160
|
annotations=TextAnnotations(),
|
|
155
161
|
)
|
|
156
162
|
|
|
163
|
+
@classmethod
|
|
164
|
+
def mention_data_source(cls, data_source_id: str) -> Self:
|
|
165
|
+
return cls(
|
|
166
|
+
type=RichTextType.MENTION,
|
|
167
|
+
mention=MentionObject(type=MentionType.DATASOURCE, data_source=MentionDataSourceRef(id=data_source_id)),
|
|
168
|
+
annotations=TextAnnotations(),
|
|
169
|
+
)
|
|
170
|
+
|
|
157
171
|
@classmethod
|
|
158
172
|
def equation_inline(cls, expression: str) -> Self:
|
|
159
173
|
return cls(
|
{notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/name_id_resolver/__init__.py
RENAMED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
from .data_source import DataSourceNameIdResolver
|
|
1
2
|
from .database import DatabaseNameIdResolver
|
|
2
3
|
from .page import PageNameIdResolver
|
|
3
4
|
from .person import PersonNameIdResolver
|
|
4
5
|
from .port import NameIdResolver
|
|
5
6
|
|
|
6
7
|
__all__ = [
|
|
8
|
+
"DataSourceNameIdResolver",
|
|
7
9
|
"DatabaseNameIdResolver",
|
|
8
10
|
"NameIdResolver",
|
|
9
11
|
"PageNameIdResolver",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from typing import override
|
|
2
|
+
|
|
3
|
+
from notionary.blocks.rich_text.name_id_resolver.port import NameIdResolver
|
|
4
|
+
from notionary.workspace.query.service import WorkspaceQueryService
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# !!! in the notion api mentions that reference datasources are not provided yet (it's a limiation of the API as of now)
|
|
8
|
+
class DataSourceNameIdResolver(NameIdResolver):
|
|
9
|
+
def __init__(self, workspace_query_service: WorkspaceQueryService | None = None) -> None:
|
|
10
|
+
self._workspace_query_service = workspace_query_service or WorkspaceQueryService()
|
|
11
|
+
|
|
12
|
+
@override
|
|
13
|
+
async def resolve_name_to_id(self, name: str) -> str | None:
|
|
14
|
+
if not name:
|
|
15
|
+
return None
|
|
16
|
+
|
|
17
|
+
cleaned_name = name.strip()
|
|
18
|
+
data_source = await self._workspace_query_service.find_data_source(query=cleaned_name)
|
|
19
|
+
return data_source.id if data_source else None
|
|
20
|
+
|
|
21
|
+
@override
|
|
22
|
+
async def resolve_id_to_name(self, data_source_id: str) -> str | None:
|
|
23
|
+
if not data_source_id:
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
from notionary import NotionDataSource
|
|
28
|
+
|
|
29
|
+
data_source = await NotionDataSource.from_id(data_source_id)
|
|
30
|
+
return data_source.title if data_source else None
|
|
31
|
+
except Exception:
|
|
32
|
+
return None
|
{notionary-0.2.28 → notionary-0.3.0}/notionary/blocks/rich_text/rich_text_markdown_converter.py
RENAMED
|
@@ -8,6 +8,7 @@ from notionary.blocks.rich_text.models import (
|
|
|
8
8
|
)
|
|
9
9
|
from notionary.blocks.rich_text.name_id_resolver import (
|
|
10
10
|
DatabaseNameIdResolver,
|
|
11
|
+
DataSourceNameIdResolver,
|
|
11
12
|
NameIdResolver,
|
|
12
13
|
PageNameIdResolver,
|
|
13
14
|
PersonNameIdResolver,
|
|
@@ -23,10 +24,12 @@ class RichTextToMarkdownConverter:
|
|
|
23
24
|
*,
|
|
24
25
|
page_resolver: NameIdResolver | None = None,
|
|
25
26
|
database_resolver: NameIdResolver | None = None,
|
|
27
|
+
data_source_resolver: NameIdResolver | None = None,
|
|
26
28
|
person_resolver: NameIdResolver | None = None,
|
|
27
29
|
) -> None:
|
|
28
30
|
self.page_resolver = page_resolver or PageNameIdResolver()
|
|
29
31
|
self.database_resolver = database_resolver or DatabaseNameIdResolver()
|
|
32
|
+
self.data_source_resolver = data_source_resolver or DataSourceNameIdResolver()
|
|
30
33
|
self.person_resolver = person_resolver or PersonNameIdResolver()
|
|
31
34
|
|
|
32
35
|
async def to_markdown(self, rich_text: list[RichText]) -> str:
|
|
@@ -65,6 +68,9 @@ class RichTextToMarkdownConverter:
|
|
|
65
68
|
elif mention.type == MentionType.DATABASE and mention.database:
|
|
66
69
|
return await self._extract_database_mention_markdown(mention.database.id)
|
|
67
70
|
|
|
71
|
+
elif mention.type == MentionType.DATASOURCE and mention.data_source:
|
|
72
|
+
return await self._extract_data_source_mention_markdown(mention.data_source.id)
|
|
73
|
+
|
|
68
74
|
elif mention.type == MentionType.USER and mention.user:
|
|
69
75
|
return await self._extract_user_mention_markdown(mention.user.id)
|
|
70
76
|
|
|
@@ -81,6 +87,10 @@ class RichTextToMarkdownConverter:
|
|
|
81
87
|
database_name = await self.database_resolver.resolve_id_to_name(database_id)
|
|
82
88
|
return f"@database[{database_name or database_id}]"
|
|
83
89
|
|
|
90
|
+
async def _extract_data_source_mention_markdown(self, data_source_id: str) -> str:
|
|
91
|
+
data_source_name = await self.data_source_resolver.resolve_id_to_name(data_source_id)
|
|
92
|
+
return f"@datasource[{data_source_name or data_source_id}]"
|
|
93
|
+
|
|
84
94
|
async def _extract_user_mention_markdown(self, user_id: str) -> str:
|
|
85
95
|
user_name = await self.person_resolver.resolve_id_to_name(user_id)
|
|
86
96
|
return f"@user[{user_name or user_id}]"
|
|
@@ -122,11 +132,13 @@ async def convert_rich_text_to_markdown(
|
|
|
122
132
|
*,
|
|
123
133
|
page_resolver: NameIdResolver | None = None,
|
|
124
134
|
database_resolver: NameIdResolver | None = None,
|
|
135
|
+
data_source_resolver: NameIdResolver | None = None,
|
|
125
136
|
person_resolver: NameIdResolver | None = None,
|
|
126
137
|
) -> str:
|
|
127
138
|
converter = RichTextToMarkdownConverter(
|
|
128
139
|
page_resolver=page_resolver,
|
|
129
140
|
database_resolver=database_resolver,
|
|
141
|
+
data_source_resolver=data_source_resolver,
|
|
130
142
|
person_resolver=person_resolver,
|
|
131
143
|
)
|
|
132
144
|
return await converter.to_markdown(rich_text)
|
|
@@ -35,5 +35,8 @@ class RichTextPatterns(StrEnum):
|
|
|
35
35
|
DATABASE_MENTION = r"@database\[([^\]]+)\]"
|
|
36
36
|
"""Matches a Notion database mention by name or ID. Example: `@database[Tasks]`."""
|
|
37
37
|
|
|
38
|
+
DATASOURCE_MENTION = r"@datasource\[([^\]]+)\]"
|
|
39
|
+
"""Matches a Notion data source mention by name or ID. Example: `@datasource[My Data]`."""
|
|
40
|
+
|
|
38
41
|
USER_MENTION = r"@user\[([^\]]+)\]"
|
|
39
42
|
"""Matches a Notion user mention by name or ID. Example: `@user[Some Person]`."""
|