notionary 0.2.28__tar.gz → 0.3.1__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.1}/PKG-INFO +35 -105
- notionary-0.3.1/README.md +190 -0
- notionary-0.3.1/notionary/__init__.py +14 -0
- notionary-0.3.1/notionary/blocks/__init__.py +5 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/client.py +6 -4
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/enums.py +28 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/rich_text/markdown_rich_text_converter.py +14 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/rich_text/models.py +14 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/rich_text/name_id_resolver/__init__.py +2 -0
- notionary-0.3.1/notionary/blocks/rich_text/name_id_resolver/data_source.py +32 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/rich_text/rich_text_markdown_converter.py +12 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/rich_text/rich_text_patterns.py +3 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/schemas.py +42 -10
- notionary-0.3.1/notionary/comments/__init__.py +5 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/comments/client.py +7 -10
- {notionary-0.2.28 → notionary-0.3.1}/notionary/comments/factory.py +4 -6
- {notionary-0.2.28 → notionary-0.3.1}/notionary/data_source/http/data_source_instance_client.py +14 -4
- notionary-0.2.28/notionary/data_source/properties/models.py → notionary-0.3.1/notionary/data_source/properties/schemas.py +4 -8
- notionary-0.3.1/notionary/data_source/query/__init__.py +9 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/data_source/query/builder.py +38 -10
- {notionary-0.2.28 → notionary-0.3.1}/notionary/data_source/query/schema.py +13 -10
- {notionary-0.2.28 → notionary-0.3.1}/notionary/data_source/query/validator.py +11 -11
- notionary-0.3.1/notionary/data_source/schema/registry.py +104 -0
- notionary-0.3.1/notionary/data_source/schema/service.py +136 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/data_source/schemas.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/data_source/service.py +29 -103
- {notionary-0.2.28 → notionary-0.3.1}/notionary/database/service.py +17 -60
- {notionary-0.2.28 → notionary-0.3.1}/notionary/exceptions/__init__.py +5 -1
- notionary-0.3.1/notionary/exceptions/block_parsing.py +37 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/exceptions/search.py +24 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/http/client.py +9 -10
- {notionary-0.2.28 → notionary-0.3.1}/notionary/http/models.py +5 -4
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/factory.py +10 -3
- notionary-0.3.1/notionary/page/content/markdown/builder.py +226 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/__init__.py +0 -2
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/audio.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/base.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/bookmark.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/breadcrumb.py +1 -1
- notionary-0.3.1/notionary/page/content/markdown/nodes/bulleted_list.py +41 -0
- notionary-0.3.1/notionary/page/content/markdown/nodes/callout.py +34 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/code.py +3 -5
- notionary-0.3.1/notionary/page/content/markdown/nodes/columns.py +69 -0
- notionary-0.3.1/notionary/page/content/markdown/nodes/container.py +64 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/divider.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/embed.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/equation.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/file.py +1 -1
- notionary-0.3.1/notionary/page/content/markdown/nodes/heading.py +36 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/image.py +1 -1
- notionary-0.3.1/notionary/page/content/markdown/nodes/mixins/__init__.py +5 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/mixins/caption.py +1 -1
- notionary-0.3.1/notionary/page/content/markdown/nodes/numbered_list.py +38 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/paragraph.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/pdf.py +1 -1
- notionary-0.3.1/notionary/page/content/markdown/nodes/quote.py +27 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/space.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/table.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/table_of_contents.py +1 -1
- notionary-0.3.1/notionary/page/content/markdown/nodes/todo.py +38 -0
- notionary-0.3.1/notionary/page/content/markdown/nodes/toggle.py +27 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/nodes/video.py +1 -1
- notionary-0.3.1/notionary/page/content/parser/context.py +126 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/factory.py +1 -10
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/__init__.py +0 -2
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/audio.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/base.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/bookmark.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/breadcrumb.py +1 -1
- notionary-0.3.1/notionary/page/content/parser/parsers/bulleted_list.py +85 -0
- notionary-0.3.1/notionary/page/content/parser/parsers/callout.py +100 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/caption.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/code.py +5 -5
- notionary-0.3.1/notionary/page/content/parser/parsers/column.py +76 -0
- notionary-0.3.1/notionary/page/content/parser/parsers/column_list.py +81 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/divider.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/embed.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/equation.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/file.py +1 -1
- notionary-0.3.1/notionary/page/content/parser/parsers/heading.py +115 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/image.py +1 -1
- notionary-0.3.1/notionary/page/content/parser/parsers/numbered_list.py +89 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/paragraph.py +3 -2
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/pdf.py +1 -1
- notionary-0.3.1/notionary/page/content/parser/parsers/quote.py +125 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/space.py +14 -8
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/table.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/table_of_contents.py +1 -1
- notionary-0.3.1/notionary/page/content/parser/parsers/todo.py +96 -0
- notionary-0.3.1/notionary/page/content/parser/parsers/toggle.py +70 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/parsers/video.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/post_processing/handlers/rich_text_length.py +6 -4
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +43 -22
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/pre_processsing/handlers/__init__.py +4 -0
- notionary-0.3.1/notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +134 -0
- notionary-0.3.1/notionary/page/content/parser/pre_processsing/handlers/indentation.py +86 -0
- notionary-0.3.1/notionary/page/content/parser/pre_processsing/handlers/video_syntax.py +66 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/pre_processsing/handlers/whitespace.py +14 -7
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/service.py +9 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/context.py +5 -2
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/factory.py +2 -11
- notionary-0.3.1/notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
- notionary-0.3.1/notionary/page/content/renderer/post_processing/handlers/numbered_list.py +156 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/__init__.py +0 -2
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/base.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/bulleted_list.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/callout.py +6 -21
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/captioned_block.py +1 -1
- notionary-0.3.1/notionary/page/content/renderer/renderers/column.py +53 -0
- notionary-0.3.1/notionary/page/content/renderer/renderers/column_list.py +44 -0
- notionary-0.3.1/notionary/page/content/renderer/renderers/heading.py +95 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/numbered_list.py +6 -5
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/quote.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/todo.py +1 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/toggle.py +6 -7
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/service.py +4 -1
- notionary-0.3.1/notionary/page/content/syntax/__init__.py +4 -0
- notionary-0.3.1/notionary/page/content/syntax/grammar.py +10 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/syntax/models.py +0 -2
- notionary-0.2.28/notionary/page/content/syntax/service.py → notionary-0.3.1/notionary/page/content/syntax/registry.py +31 -91
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/properties/client.py +3 -3
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/properties/models.py +3 -2
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/properties/service.py +18 -3
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/service.py +22 -80
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/entity/service.py +94 -36
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/models/cover.py +1 -1
- notionary-0.3.1/notionary/shared/typings.py +3 -0
- notionary-0.3.1/notionary/user/base.py +138 -0
- notionary-0.3.1/notionary/user/factory.py +0 -0
- notionary-0.3.1/notionary/utils/decorators.py +122 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/utils/fuzzy.py +18 -6
- notionary-0.3.1/notionary/utils/mixins/logging.py +58 -0
- notionary-0.3.1/notionary/utils/pagination.py +104 -0
- notionary-0.3.1/notionary/workspace/__init__.py +4 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/workspace/client.py +4 -2
- notionary-0.3.1/notionary/workspace/query/__init__.py +3 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/workspace/query/builder.py +25 -1
- {notionary-0.2.28 → notionary-0.3.1}/notionary/workspace/query/models.py +12 -3
- notionary-0.3.1/notionary/workspace/query/service.py +118 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/workspace/service.py +31 -21
- {notionary-0.2.28 → notionary-0.3.1}/pyproject.toml +2 -2
- notionary-0.2.28/README.md +0 -260
- notionary-0.2.28/notionary/__init__.py +0 -7
- notionary-0.2.28/notionary/exceptions/block_parsing.py +0 -16
- 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/workspace/query/service.py +0 -93
- {notionary-0.2.28 → notionary-0.3.1}/.gitignore +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/LICENSE +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/rich_text/name_id_resolver/database.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/rich_text/name_id_resolver/page.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/rich_text/name_id_resolver/person.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/blocks/rich_text/name_id_resolver/port.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/comments/models.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/comments/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/comments/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/data_source/http/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/data_source/query/resolver.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/database/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/database/database_metadata_update_client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/database/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/exceptions/api.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/exceptions/base.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/exceptions/data_source/__init__.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/exceptions/data_source/builder.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/exceptions/data_source/properties.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/exceptions/properties.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/file_upload/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/file_upload/models.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/file_upload/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/blocks/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/markdown/__init__.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/post_processing/handlers/__init__.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/post_processing/port.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/post_processing/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/pre_processsing/handlers/port.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/parser/pre_processsing/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/post_processing/port.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/post_processing/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/audio.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/bookmark.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/breadcrumb.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/code.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/divider.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/embed.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/equation.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/fallback.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/file.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/image.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/paragraph.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/pdf.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/table.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/table_of_contents.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/table_row.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/renderers/video.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/content/renderer/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/page_context.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/page_http_client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/page_metadata_update_client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/properties/factory.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/page/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/entity/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/entity/dto_parsers.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/entity/entity_metadata_update_client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/entity/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/models/file.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/models/icon.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/models/parent.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/shared/properties/type.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/user/__init__.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/user/bot.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/user/client.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/user/person.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/user/schemas.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/user/service.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/utils/date.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/utils/uuid_utils.py +0 -0
- {notionary-0.2.28 → notionary-0.3.1}/notionary/workspace/schemas.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: notionary
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
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>
|
|
7
7
|
License: MIT
|
|
8
8
|
License-File: LICENSE
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.12
|
|
10
10
|
Requires-Dist: aiofiles<25.0.0,>=24.1.0
|
|
11
11
|
Requires-Dist: httpx>=0.28.0
|
|
12
12
|
Requires-Dist: pydantic>=2.11.4
|
|
@@ -23,9 +23,13 @@ Description-Content-Type: text/markdown
|
|
|
23
23
|
|
|
24
24
|
<div align="center">
|
|
25
25
|
|
|
26
|
-
[](https://badge.fury.io/py/notionary)
|
|
27
|
+
[](https://www.python.org/downloads/)
|
|
28
|
+
[](https://opensource.org/licenses/MIT)
|
|
29
|
+
[](https://github.com/mathisarends/notionary)
|
|
30
|
+
[](https://pypi.org/project/notionary/)
|
|
31
|
+
[](https://mathisarends.github.io/notionary/)
|
|
32
|
+
[](https://developers.notion.com/)
|
|
29
33
|
|
|
30
34
|
**Transform complex Notion API interactions into simple, Pythonic code.**
|
|
31
35
|
Perfect for developers building AI agents, automation workflows, and dynamic content systems.
|
|
@@ -61,17 +65,9 @@ export NOTION_SECRET=your_integration_key
|
|
|
61
65
|
|
|
62
66
|
## See It in Action
|
|
63
67
|
|
|
64
|
-
### Creating Rich Database Entries
|
|
65
|
-
|
|
66
68
|
https://github.com/user-attachments/assets/da8b4691-bee4-4b0f-801e-dccacb630398
|
|
67
69
|
|
|
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_
|
|
70
|
+
_Create rich database entries with properties, content, and beautiful formatting_
|
|
75
71
|
|
|
76
72
|
---
|
|
77
73
|
|
|
@@ -80,50 +76,30 @@ _Upload videos and images using simple markdown syntax - files are automatically
|
|
|
80
76
|
### Find → Create → Update Flow
|
|
81
77
|
|
|
82
78
|
```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())
|
|
79
|
+
from notionary import NotionPage
|
|
80
|
+
|
|
81
|
+
# Find pages by name with fuzzy matching
|
|
82
|
+
page = await NotionPage.from_title("Meeting Notes")
|
|
83
|
+
|
|
84
|
+
# Define rich content with extended markdown
|
|
85
|
+
content = """
|
|
86
|
+
## Action Items
|
|
87
|
+
- [x] Review proposal
|
|
88
|
+
- [ ] Schedule meeting
|
|
89
|
+
|
|
90
|
+
[callout](Key decision made! "💡")
|
|
91
|
+
|
|
92
|
+
| Task | Owner | Deadline |
|
|
93
|
+
|------|-------|----------|
|
|
94
|
+
| Design Review | Alice | 2024-03-15 |
|
|
95
|
+
| Implementation | Bob | 2024-03-22 |
|
|
96
|
+
|
|
97
|
+
+++ Budget Details
|
|
98
|
+
See attached spreadsheet...
|
|
99
|
+
+++
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
await page.append_markdown(content)
|
|
127
103
|
```
|
|
128
104
|
|
|
129
105
|
### Complete Block Support
|
|
@@ -132,36 +108,13 @@ Every Notion block type with extended syntax:
|
|
|
132
108
|
|
|
133
109
|
| Block Type | Markdown Syntax | Use Case |
|
|
134
110
|
| ------------- | -------------------------------------------- | ---------------------------- |
|
|
135
|
-
| **Callouts** | `[callout](Text "🔥")` | Highlighting key information |
|
|
136
111
|
| **Toggles** | `+++ Title\nContent\n+++` | Collapsible sections |
|
|
137
112
|
| **Columns** | `::: columns\n::: column\nContent\n:::\n:::` | Side-by-side layouts |
|
|
138
113
|
| **Tables** | Standard markdown tables | Structured data |
|
|
139
114
|
| **Media** | `[video](./file.mp4)(caption:Description)` | Auto-uploading files |
|
|
140
115
|
| **Code** | Standard code fences with captions | Code snippets |
|
|
141
116
|
| **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
|
|
117
|
+
| **TOC** | `[toc]` | Auto-generated navigation |
|
|
165
118
|
|
|
166
119
|
---
|
|
167
120
|
|
|
@@ -222,29 +175,6 @@ Every Notion block type with extended syntax:
|
|
|
222
175
|
|
|
223
176
|
[**mathisarends.github.io/notionary**](https://mathisarends.github.io/notionary/) - Complete API reference, guides, and tutorials
|
|
224
177
|
|
|
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
178
|
---
|
|
249
179
|
|
|
250
180
|
## Contributing
|
|
@@ -0,0 +1,190 @@
|
|
|
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://badge.fury.io/py/notionary)
|
|
12
|
+
[](https://www.python.org/downloads/)
|
|
13
|
+
[](https://opensource.org/licenses/MIT)
|
|
14
|
+
[](https://github.com/mathisarends/notionary)
|
|
15
|
+
[](https://pypi.org/project/notionary/)
|
|
16
|
+
[](https://mathisarends.github.io/notionary/)
|
|
17
|
+
[](https://developers.notion.com/)
|
|
18
|
+
|
|
19
|
+
**Transform complex Notion API interactions into simple, Pythonic code.**
|
|
20
|
+
Perfect for developers building AI agents, automation workflows, and dynamic content systems.
|
|
21
|
+
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Why Notionary?
|
|
27
|
+
|
|
28
|
+
- **AI-Native Design** - Built specifically for AI agents with schema-driven markdown syntax
|
|
29
|
+
- **Smart Discovery** - Find pages and databases by name with fuzzy matching—no more hunting for IDs
|
|
30
|
+
- **Extended Markdown** - Rich syntax for toggles, columns, callouts, and media uploads
|
|
31
|
+
- **Async-First** - Modern Python with full async/await support and high performance
|
|
32
|
+
- **Round-Trip** - Read existing content, modify it, and write it back while preserving formatting
|
|
33
|
+
- **Complete Coverage** - Every Notion block type supported with type safety
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install notionary
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Set up your [Notion integration](https://www.notion.so/profile/integrations) and configure your token:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export NOTION_SECRET=your_integration_key
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## See It in Action
|
|
52
|
+
|
|
53
|
+
https://github.com/user-attachments/assets/da8b4691-bee4-4b0f-801e-dccacb630398
|
|
54
|
+
|
|
55
|
+
_Create rich database entries with properties, content, and beautiful formatting_
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
### Find → Create → Update Flow
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from notionary import NotionPage
|
|
65
|
+
|
|
66
|
+
# Find pages by name with fuzzy matching
|
|
67
|
+
page = await NotionPage.from_title("Meeting Notes")
|
|
68
|
+
|
|
69
|
+
# Define rich content with extended markdown
|
|
70
|
+
content = """
|
|
71
|
+
## Action Items
|
|
72
|
+
- [x] Review proposal
|
|
73
|
+
- [ ] Schedule meeting
|
|
74
|
+
|
|
75
|
+
[callout](Key decision made! "💡")
|
|
76
|
+
|
|
77
|
+
| Task | Owner | Deadline |
|
|
78
|
+
|------|-------|----------|
|
|
79
|
+
| Design Review | Alice | 2024-03-15 |
|
|
80
|
+
| Implementation | Bob | 2024-03-22 |
|
|
81
|
+
|
|
82
|
+
+++ Budget Details
|
|
83
|
+
See attached spreadsheet...
|
|
84
|
+
+++
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
await page.append_markdown(content)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Complete Block Support
|
|
91
|
+
|
|
92
|
+
Every Notion block type with extended syntax:
|
|
93
|
+
|
|
94
|
+
| Block Type | Markdown Syntax | Use Case |
|
|
95
|
+
| ------------- | -------------------------------------------- | ---------------------------- |
|
|
96
|
+
| **Toggles** | `+++ Title\nContent\n+++` | Collapsible sections |
|
|
97
|
+
| **Columns** | `::: columns\n::: column\nContent\n:::\n:::` | Side-by-side layouts |
|
|
98
|
+
| **Tables** | Standard markdown tables | Structured data |
|
|
99
|
+
| **Media** | `[video](./file.mp4)(caption:Description)` | Auto-uploading files |
|
|
100
|
+
| **Code** | Standard code fences with captions | Code snippets |
|
|
101
|
+
| **Equations** | `$LaTeX$` | Mathematical expressions |
|
|
102
|
+
| **TOC** | `[toc]` | Auto-generated navigation |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Key Features
|
|
107
|
+
|
|
108
|
+
<table>
|
|
109
|
+
<tr>
|
|
110
|
+
<td width="50%">
|
|
111
|
+
|
|
112
|
+
### Smart Discovery
|
|
113
|
+
|
|
114
|
+
- Find pages/databases by name
|
|
115
|
+
- Fuzzy matching for approximate searches
|
|
116
|
+
- No more hunting for IDs or URLs
|
|
117
|
+
|
|
118
|
+
### Extended Markdown
|
|
119
|
+
|
|
120
|
+
- Rich syntax beyond standard markdown
|
|
121
|
+
- Callouts, toggles, columns, media uploads
|
|
122
|
+
- Schema provided for AI agent integration
|
|
123
|
+
|
|
124
|
+
### Modern Python
|
|
125
|
+
|
|
126
|
+
- Full async/await support
|
|
127
|
+
- Type hints throughout
|
|
128
|
+
- High-performance batch operations
|
|
129
|
+
|
|
130
|
+
</td>
|
|
131
|
+
<td width="50%">
|
|
132
|
+
|
|
133
|
+
### Round-Trip Editing
|
|
134
|
+
|
|
135
|
+
- Read existing content as markdown
|
|
136
|
+
- Edit and modify preserving formatting
|
|
137
|
+
- Write back to Notion seamlessly
|
|
138
|
+
|
|
139
|
+
### AI-Ready Architecture
|
|
140
|
+
|
|
141
|
+
- Schema-driven syntax for LLM prompts
|
|
142
|
+
- Perfect for AI content generation
|
|
143
|
+
- Handles complex nested structures
|
|
144
|
+
|
|
145
|
+
### Complete Coverage
|
|
146
|
+
|
|
147
|
+
- Every Notion block type supported
|
|
148
|
+
- File uploads with automatic handling
|
|
149
|
+
- Database operations and properties
|
|
150
|
+
|
|
151
|
+
</td>
|
|
152
|
+
</tr>
|
|
153
|
+
</table>
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Examples & Documentation
|
|
158
|
+
|
|
159
|
+
### Full Documentation
|
|
160
|
+
|
|
161
|
+
[**mathisarends.github.io/notionary**](https://mathisarends.github.io/notionary/) - Complete API reference, guides, and tutorials
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Contributing
|
|
166
|
+
|
|
167
|
+
We welcome contributions from the community! Whether you're:
|
|
168
|
+
|
|
169
|
+
- **Fixing bugs** - Help improve stability and reliability
|
|
170
|
+
- **Adding features** - Extend functionality for new use cases
|
|
171
|
+
- **Improving docs** - Make the library more accessible
|
|
172
|
+
- **Sharing examples** - Show creative applications and patterns
|
|
173
|
+
|
|
174
|
+
Check our [**Contributing Guide**](https://mathisarends.github.io/notionary/contributing/) to get started.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
<div align="center">
|
|
179
|
+
|
|
180
|
+
**Ready to revolutionize your Notion workflows?**
|
|
181
|
+
|
|
182
|
+
[📖 **Read the Docs**](https://mathisarends.github.io/notionary/) • [🚀 **Getting Started**](https://mathisarends.github.io/notionary/get-started/) • [💻 **Browse Examples**](examples/)
|
|
183
|
+
|
|
184
|
+
_Built with ❤️ for Python developers and AI agents_
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
**Transform complex Notion API interactions into simple, powerful code.**
|
|
189
|
+
|
|
190
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
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, NotionWorkspaceQueryConfigBuilder
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"MarkdownBuilder",
|
|
9
|
+
"NotionDataSource",
|
|
10
|
+
"NotionDatabase",
|
|
11
|
+
"NotionPage",
|
|
12
|
+
"NotionWorkspace",
|
|
13
|
+
"NotionWorkspaceQueryConfigBuilder",
|
|
14
|
+
]
|
|
@@ -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:
|
|
@@ -68,7 +68,7 @@ class FileType(StrEnum):
|
|
|
68
68
|
FILE_UPLOAD = "file_upload"
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
class
|
|
71
|
+
class CodingLanguage(StrEnum):
|
|
72
72
|
ABAP = "abap"
|
|
73
73
|
ARDUINO = "arduino"
|
|
74
74
|
BASH = "bash"
|
|
@@ -165,3 +165,30 @@ class CodeLanguage(StrEnum):
|
|
|
165
165
|
return member
|
|
166
166
|
|
|
167
167
|
return default if default is not None else cls.PLAIN_TEXT
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class VideoFileType(StrEnum):
|
|
171
|
+
AMV = ".amv"
|
|
172
|
+
ASF = ".asf"
|
|
173
|
+
AVI = ".avi"
|
|
174
|
+
F4V = ".f4v"
|
|
175
|
+
FLV = ".flv"
|
|
176
|
+
GIFV = ".gifv"
|
|
177
|
+
MKV = ".mkv"
|
|
178
|
+
MOV = ".mov"
|
|
179
|
+
MPG = ".mpg"
|
|
180
|
+
MPEG = ".mpeg"
|
|
181
|
+
MPV = ".mpv"
|
|
182
|
+
MP4 = ".mp4"
|
|
183
|
+
M4V = ".m4v"
|
|
184
|
+
QT = ".qt"
|
|
185
|
+
WMV = ".wmv"
|
|
186
|
+
|
|
187
|
+
@classmethod
|
|
188
|
+
def get_all_extensions(cls) -> set[str]:
|
|
189
|
+
return {ext.value for ext in cls}
|
|
190
|
+
|
|
191
|
+
@classmethod
|
|
192
|
+
def is_valid_extension(cls, filename: str) -> bool:
|
|
193
|
+
lower_filename = filename.lower()
|
|
194
|
+
return any(lower_filename.endswith(ext.value) for ext in cls)
|
{notionary-0.2.28 → notionary-0.3.1}/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.1}/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.1}/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)
|