notionary 0.2.27__py3-none-any.whl → 0.2.28__py3-none-any.whl
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/__init__.py +5 -20
- notionary/blocks/client.py +87 -215
- notionary/blocks/enums.py +167 -0
- notionary/blocks/rich_text/markdown_rich_text_converter.py +266 -0
- notionary/blocks/rich_text/models.py +164 -0
- notionary/blocks/rich_text/name_id_resolver/__init__.py +11 -0
- notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
- notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
- notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
- notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
- notionary/blocks/rich_text/rich_text_markdown_converter.py +132 -0
- notionary/blocks/rich_text/rich_text_patterns.py +39 -0
- notionary/blocks/schemas.py +746 -0
- notionary/comments/client.py +52 -187
- notionary/comments/factory.py +40 -0
- notionary/comments/models.py +5 -127
- notionary/comments/schemas.py +240 -0
- notionary/comments/service.py +34 -0
- notionary/data_source/http/client.py +11 -0
- notionary/data_source/http/data_source_instance_client.py +94 -0
- notionary/data_source/properties/models.py +406 -0
- notionary/data_source/query/builder.py +429 -0
- notionary/data_source/query/resolver.py +114 -0
- notionary/data_source/query/schema.py +304 -0
- notionary/data_source/query/validator.py +73 -0
- notionary/data_source/schemas.py +27 -0
- notionary/data_source/service.py +353 -0
- notionary/database/client.py +30 -135
- notionary/database/database_metadata_update_client.py +19 -0
- notionary/database/schemas.py +29 -0
- notionary/database/service.py +169 -0
- notionary/exceptions/__init__.py +33 -0
- notionary/exceptions/api.py +41 -0
- notionary/exceptions/base.py +2 -0
- notionary/exceptions/block_parsing.py +16 -0
- notionary/exceptions/data_source/__init__.py +6 -0
- notionary/exceptions/data_source/builder.py +182 -0
- notionary/exceptions/data_source/properties.py +34 -0
- notionary/exceptions/properties.py +58 -0
- notionary/exceptions/search.py +33 -0
- notionary/file_upload/client.py +18 -30
- notionary/file_upload/models.py +7 -8
- notionary/file_upload/{notion_file_upload.py → service.py} +29 -64
- notionary/http/client.py +205 -0
- notionary/http/models.py +49 -0
- notionary/page/blocks/client.py +1 -0
- notionary/page/content/factory.py +68 -0
- notionary/page/content/markdown/__init__.py +5 -0
- notionary/page/content/markdown/builder.py +304 -0
- notionary/page/content/markdown/nodes/__init__.py +54 -0
- notionary/page/content/markdown/nodes/audio.py +23 -0
- notionary/page/content/markdown/nodes/base.py +12 -0
- notionary/page/content/markdown/nodes/bookmark.py +25 -0
- notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
- notionary/page/content/markdown/nodes/bulleted_list.py +18 -0
- notionary/page/content/markdown/nodes/callout.py +32 -0
- notionary/page/content/markdown/nodes/code.py +30 -0
- notionary/page/content/markdown/nodes/columns.py +51 -0
- notionary/page/content/markdown/nodes/divider.py +14 -0
- notionary/page/content/markdown/nodes/embed.py +23 -0
- notionary/page/content/markdown/nodes/equation.py +19 -0
- notionary/page/content/markdown/nodes/file.py +23 -0
- notionary/page/content/markdown/nodes/heading.py +16 -0
- notionary/page/content/markdown/nodes/image.py +23 -0
- notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
- notionary/page/content/markdown/nodes/numbered_list.py +15 -0
- notionary/page/content/markdown/nodes/paragraph.py +14 -0
- notionary/page/content/markdown/nodes/pdf.py +23 -0
- notionary/page/content/markdown/nodes/quote.py +15 -0
- notionary/page/content/markdown/nodes/space.py +14 -0
- notionary/page/content/markdown/nodes/table.py +45 -0
- notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
- notionary/page/content/markdown/nodes/todo.py +22 -0
- notionary/page/content/markdown/nodes/toggle.py +28 -0
- notionary/page/content/markdown/nodes/toggleable_heading.py +35 -0
- notionary/page/content/markdown/nodes/video.py +23 -0
- notionary/page/content/parser/context.py +49 -0
- notionary/page/content/parser/factory.py +219 -0
- notionary/page/content/parser/parsers/__init__.py +60 -0
- notionary/page/content/parser/parsers/audio.py +40 -0
- notionary/page/content/parser/parsers/base.py +30 -0
- notionary/page/content/parser/parsers/bookmark.py +33 -0
- notionary/page/content/parser/parsers/breadcrumb.py +33 -0
- notionary/page/content/parser/parsers/bulleted_list.py +41 -0
- notionary/page/content/parser/parsers/callout.py +129 -0
- notionary/page/content/parser/parsers/caption.py +55 -0
- notionary/page/content/parser/parsers/code.py +81 -0
- notionary/page/content/parser/parsers/column.py +117 -0
- notionary/page/content/parser/parsers/column_list.py +81 -0
- notionary/page/content/parser/parsers/divider.py +33 -0
- notionary/page/content/parser/parsers/embed.py +33 -0
- notionary/page/content/parser/parsers/equation.py +65 -0
- notionary/page/content/parser/parsers/file.py +42 -0
- notionary/page/content/parser/parsers/heading.py +58 -0
- notionary/page/content/parser/parsers/image.py +42 -0
- notionary/page/content/parser/parsers/numbered_list.py +45 -0
- notionary/page/content/parser/parsers/paragraph.py +36 -0
- notionary/page/content/parser/parsers/pdf.py +42 -0
- notionary/page/content/parser/parsers/quote.py +65 -0
- notionary/page/content/parser/parsers/space.py +35 -0
- notionary/page/content/parser/parsers/table.py +144 -0
- notionary/page/content/parser/parsers/table_of_contents.py +32 -0
- notionary/page/content/parser/parsers/todo.py +58 -0
- notionary/page/content/parser/parsers/toggle.py +127 -0
- notionary/page/content/parser/parsers/toggleable_heading.py +150 -0
- notionary/page/content/parser/parsers/video.py +42 -0
- notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
- notionary/page/content/parser/post_processing/handlers/rich_text_length.py +93 -0
- notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +93 -0
- notionary/page/content/parser/post_processing/port.py +9 -0
- notionary/page/content/parser/post_processing/service.py +16 -0
- notionary/page/content/parser/pre_processsing/handlers/__init__.py +9 -0
- notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +80 -0
- notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
- notionary/page/content/parser/pre_processsing/handlers/whitespace.py +68 -0
- notionary/page/content/parser/pre_processsing/service.py +15 -0
- notionary/page/content/parser/service.py +69 -0
- notionary/page/content/renderer/context.py +48 -0
- notionary/page/content/renderer/factory.py +240 -0
- notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
- notionary/page/content/renderer/post_processing/handlers/numbered_list_placeholdere.py +62 -0
- notionary/page/content/renderer/post_processing/port.py +7 -0
- notionary/page/content/renderer/post_processing/service.py +15 -0
- notionary/page/content/renderer/renderers/__init__.py +57 -0
- notionary/page/content/renderer/renderers/audio.py +31 -0
- notionary/page/content/renderer/renderers/base.py +31 -0
- notionary/page/content/renderer/renderers/bookmark.py +25 -0
- notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
- notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
- notionary/page/content/renderer/renderers/callout.py +65 -0
- notionary/page/content/renderer/renderers/captioned_block.py +58 -0
- notionary/page/content/renderer/renderers/code.py +34 -0
- notionary/page/content/renderer/renderers/column.py +44 -0
- notionary/page/content/renderer/renderers/column_list.py +31 -0
- notionary/page/content/renderer/renderers/divider.py +22 -0
- notionary/page/content/renderer/renderers/embed.py +25 -0
- notionary/page/content/renderer/renderers/equation.py +37 -0
- notionary/page/content/renderer/renderers/fallback.py +24 -0
- notionary/page/content/renderer/renderers/file.py +40 -0
- notionary/page/content/renderer/renderers/heading.py +69 -0
- notionary/page/content/renderer/renderers/image.py +31 -0
- notionary/page/content/renderer/renderers/numbered_list.py +41 -0
- notionary/page/content/renderer/renderers/paragraph.py +40 -0
- notionary/page/content/renderer/renderers/pdf.py +31 -0
- notionary/page/content/renderer/renderers/quote.py +49 -0
- notionary/page/content/renderer/renderers/table.py +115 -0
- notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
- notionary/page/content/renderer/renderers/table_row.py +17 -0
- notionary/page/content/renderer/renderers/todo.py +56 -0
- notionary/page/content/renderer/renderers/toggle.py +53 -0
- notionary/page/content/renderer/renderers/toggleable_heading.py +78 -0
- notionary/page/content/renderer/renderers/video.py +31 -0
- notionary/page/content/renderer/service.py +50 -0
- notionary/page/content/service.py +65 -0
- notionary/page/content/syntax/models.py +68 -0
- notionary/page/content/syntax/service.py +453 -0
- notionary/page/page_context.py +7 -16
- notionary/page/page_http_client.py +15 -0
- notionary/page/page_metadata_update_client.py +19 -0
- notionary/page/properties/client.py +144 -0
- notionary/page/properties/factory.py +26 -0
- notionary/page/properties/models.py +307 -0
- notionary/page/properties/service.py +257 -0
- notionary/page/schemas.py +13 -0
- notionary/page/service.py +222 -0
- notionary/shared/entity/client.py +29 -0
- notionary/shared/entity/dto_parsers.py +53 -0
- notionary/shared/entity/entity_metadata_update_client.py +41 -0
- notionary/shared/entity/schemas.py +45 -0
- notionary/shared/entity/service.py +171 -0
- notionary/shared/models/cover.py +20 -0
- notionary/shared/models/file.py +21 -0
- notionary/shared/models/icon.py +28 -0
- notionary/shared/models/parent.py +41 -0
- notionary/shared/properties/type.py +30 -0
- notionary/user/__init__.py +4 -8
- notionary/user/base.py +89 -0
- notionary/user/bot.py +70 -0
- notionary/user/client.py +22 -111
- notionary/user/person.py +41 -0
- notionary/user/schemas.py +67 -0
- notionary/user/service.py +65 -0
- notionary/utils/async_retry.py +39 -0
- notionary/utils/date.py +51 -0
- notionary/utils/fuzzy.py +56 -0
- notionary/{util/logging_mixin.py → utils/mixins/logging.py} +4 -16
- notionary/utils/pagination.py +50 -0
- notionary/utils/singleton.py +13 -0
- notionary/utils/uuid_utils.py +20 -0
- notionary/workspace/__init__.py +3 -0
- notionary/workspace/client.py +62 -0
- notionary/workspace/query/builder.py +60 -0
- notionary/workspace/query/models.py +60 -0
- notionary/workspace/query/service.py +93 -0
- notionary/workspace/schemas.py +21 -0
- notionary/workspace/service.py +116 -0
- {notionary-0.2.27.dist-info → notionary-0.2.28.dist-info}/METADATA +54 -49
- notionary-0.2.28.dist-info/RECORD +200 -0
- {notionary-0.2.27.dist-info → notionary-0.2.28.dist-info}/WHEEL +1 -1
- {notionary-0.2.27.dist-info → notionary-0.2.28.dist-info/licenses}/LICENSE +9 -9
- notionary/base_notion_client.py +0 -219
- notionary/blocks/__init__.py +0 -5
- notionary/blocks/_bootstrap.py +0 -271
- notionary/blocks/audio/__init__.py +0 -11
- notionary/blocks/audio/audio_element.py +0 -158
- notionary/blocks/audio/audio_markdown_node.py +0 -24
- notionary/blocks/audio/audio_models.py +0 -10
- notionary/blocks/base_block_element.py +0 -42
- notionary/blocks/bookmark/__init__.py +0 -12
- notionary/blocks/bookmark/bookmark_element.py +0 -83
- notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
- notionary/blocks/bookmark/bookmark_models.py +0 -15
- notionary/blocks/breadcrumbs/__init__.py +0 -15
- notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
- notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
- notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
- notionary/blocks/bulleted_list/__init__.py +0 -15
- notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
- notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
- notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
- notionary/blocks/callout/__init__.py +0 -12
- notionary/blocks/callout/callout_element.py +0 -99
- notionary/blocks/callout/callout_markdown_node.py +0 -19
- notionary/blocks/callout/callout_models.py +0 -33
- notionary/blocks/child_database/__init__.py +0 -14
- notionary/blocks/child_database/child_database_element.py +0 -59
- notionary/blocks/child_database/child_database_models.py +0 -12
- notionary/blocks/child_page/__init__.py +0 -9
- notionary/blocks/child_page/child_page_element.py +0 -94
- notionary/blocks/child_page/child_page_models.py +0 -12
- notionary/blocks/code/__init__.py +0 -11
- notionary/blocks/code/code_element.py +0 -149
- notionary/blocks/code/code_markdown_node.py +0 -80
- notionary/blocks/code/code_models.py +0 -94
- notionary/blocks/column/__init__.py +0 -25
- notionary/blocks/column/column_element.py +0 -65
- notionary/blocks/column/column_list_element.py +0 -52
- notionary/blocks/column/column_list_markdown_node.py +0 -34
- notionary/blocks/column/column_markdown_node.py +0 -42
- notionary/blocks/column/column_models.py +0 -26
- notionary/blocks/divider/__init__.py +0 -12
- notionary/blocks/divider/divider_element.py +0 -41
- notionary/blocks/divider/divider_markdown_node.py +0 -11
- notionary/blocks/divider/divider_models.py +0 -12
- notionary/blocks/embed/__init__.py +0 -12
- notionary/blocks/embed/embed_element.py +0 -98
- notionary/blocks/embed/embed_markdown_node.py +0 -19
- notionary/blocks/embed/embed_models.py +0 -14
- notionary/blocks/equation/__init__.py +0 -13
- notionary/blocks/equation/equation_element.py +0 -133
- notionary/blocks/equation/equation_element_markdown_node.py +0 -23
- notionary/blocks/equation/equation_models.py +0 -11
- notionary/blocks/file/__init__.py +0 -23
- notionary/blocks/file/file_element.py +0 -133
- notionary/blocks/file/file_element_markdown_node.py +0 -24
- notionary/blocks/file/file_element_models.py +0 -39
- notionary/blocks/heading/__init__.py +0 -19
- notionary/blocks/heading/heading_element.py +0 -112
- notionary/blocks/heading/heading_markdown_node.py +0 -16
- notionary/blocks/heading/heading_models.py +0 -29
- notionary/blocks/image_block/__init__.py +0 -11
- notionary/blocks/image_block/image_element.py +0 -130
- notionary/blocks/image_block/image_markdown_node.py +0 -25
- notionary/blocks/image_block/image_models.py +0 -10
- notionary/blocks/markdown/markdown_builder.py +0 -525
- notionary/blocks/markdown/markdown_document_model.py +0 -0
- notionary/blocks/markdown/markdown_node.py +0 -25
- notionary/blocks/mixins/captions/__init__.py +0 -4
- notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
- notionary/blocks/mixins/captions/caption_mixin.py +0 -92
- notionary/blocks/mixins/file_upload/__init__.py +0 -3
- notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
- notionary/blocks/models.py +0 -174
- notionary/blocks/numbered_list/__init__.py +0 -16
- notionary/blocks/numbered_list/numbered_list_element.py +0 -65
- notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
- notionary/blocks/numbered_list/numbered_list_models.py +0 -17
- notionary/blocks/paragraph/__init__.py +0 -15
- notionary/blocks/paragraph/paragraph_element.py +0 -58
- notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
- notionary/blocks/paragraph/paragraph_models.py +0 -16
- notionary/blocks/pdf/__init__.py +0 -11
- notionary/blocks/pdf/pdf_element.py +0 -146
- notionary/blocks/pdf/pdf_markdown_node.py +0 -24
- notionary/blocks/pdf/pdf_models.py +0 -11
- notionary/blocks/quote/__init__.py +0 -14
- notionary/blocks/quote/quote_element.py +0 -75
- notionary/blocks/quote/quote_markdown_node.py +0 -16
- notionary/blocks/quote/quote_models.py +0 -18
- notionary/blocks/registry/__init__.py +0 -3
- notionary/blocks/registry/block_registry.py +0 -150
- notionary/blocks/rich_text/__init__.py +0 -33
- notionary/blocks/rich_text/rich_text_models.py +0 -221
- notionary/blocks/rich_text/text_inline_formatter.py +0 -456
- notionary/blocks/syntax_prompt_builder.py +0 -137
- notionary/blocks/table/__init__.py +0 -19
- notionary/blocks/table/table_element.py +0 -225
- notionary/blocks/table/table_markdown_node.py +0 -42
- notionary/blocks/table/table_models.py +0 -28
- notionary/blocks/table_of_contents/__init__.py +0 -17
- notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
- notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
- notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
- notionary/blocks/todo/__init__.py +0 -12
- notionary/blocks/todo/todo_element.py +0 -81
- notionary/blocks/todo/todo_markdown_node.py +0 -21
- notionary/blocks/todo/todo_models.py +0 -18
- notionary/blocks/toggle/__init__.py +0 -12
- notionary/blocks/toggle/toggle_element.py +0 -112
- notionary/blocks/toggle/toggle_markdown_node.py +0 -31
- notionary/blocks/toggle/toggle_models.py +0 -17
- notionary/blocks/toggleable_heading/__init__.py +0 -11
- notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
- notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
- notionary/blocks/types.py +0 -130
- notionary/blocks/video/__init__.py +0 -11
- notionary/blocks/video/video_element.py +0 -187
- notionary/blocks/video/video_element_models.py +0 -10
- notionary/blocks/video/video_markdown_node.py +0 -26
- notionary/comments/__init__.py +0 -26
- notionary/database/__init__.py +0 -4
- notionary/database/database.py +0 -480
- notionary/database/database_filter_builder.py +0 -173
- notionary/database/database_provider.py +0 -227
- notionary/database/exceptions.py +0 -13
- notionary/database/factory.py +0 -0
- notionary/database/models.py +0 -337
- notionary/database/notion_database.py +0 -487
- notionary/file_upload/__init__.py +0 -7
- notionary/page/client.py +0 -124
- notionary/page/markdown_whitespace_processor.py +0 -129
- notionary/page/models.py +0 -322
- notionary/page/notion_page.py +0 -712
- notionary/page/page_content_deleting_service.py +0 -117
- notionary/page/page_content_writer.py +0 -80
- notionary/page/property_formatter.py +0 -99
- notionary/page/reader/handler/__init__.py +0 -19
- notionary/page/reader/handler/base_block_renderer.py +0 -44
- notionary/page/reader/handler/block_processing_context.py +0 -35
- notionary/page/reader/handler/block_rendering_context.py +0 -48
- notionary/page/reader/handler/column_list_renderer.py +0 -51
- notionary/page/reader/handler/column_renderer.py +0 -60
- notionary/page/reader/handler/equation_renderer.py +0 -0
- notionary/page/reader/handler/line_renderer.py +0 -73
- notionary/page/reader/handler/numbered_list_renderer.py +0 -85
- notionary/page/reader/handler/toggle_renderer.py +0 -69
- notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
- notionary/page/reader/page_content_retriever.py +0 -81
- notionary/page/search_filter_builder.py +0 -132
- notionary/page/utils.py +0 -60
- notionary/page/writer/handler/__init__.py +0 -24
- notionary/page/writer/handler/code_handler.py +0 -72
- notionary/page/writer/handler/column_handler.py +0 -141
- notionary/page/writer/handler/column_list_handler.py +0 -139
- notionary/page/writer/handler/equation_handler.py +0 -74
- notionary/page/writer/handler/line_handler.py +0 -35
- notionary/page/writer/handler/line_processing_context.py +0 -54
- notionary/page/writer/handler/regular_line_handler.py +0 -86
- notionary/page/writer/handler/table_handler.py +0 -66
- notionary/page/writer/handler/toggle_handler.py +0 -159
- notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
- notionary/page/writer/markdown_to_notion_converter.py +0 -139
- notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
- notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
- notionary/page/writer/notion_text_length_processor.py +0 -150
- notionary/schemas/__init__.py +0 -3
- notionary/schemas/base.py +0 -73
- notionary/shared/__init__.py +0 -3
- notionary/shared/name_to_id_resolver.py +0 -203
- notionary/telemetry/__init__.py +0 -19
- notionary/telemetry/service.py +0 -136
- notionary/telemetry/views.py +0 -73
- notionary/user/base_notion_user.py +0 -53
- notionary/user/models.py +0 -84
- notionary/user/notion_bot_user.py +0 -226
- notionary/user/notion_user.py +0 -255
- notionary/user/notion_user_manager.py +0 -101
- notionary/util/__init__.py +0 -15
- notionary/util/concurrency_limiter.py +0 -0
- notionary/util/factory_decorator.py +0 -0
- notionary/util/factory_only.py +0 -37
- notionary/util/fuzzy.py +0 -75
- notionary/util/page_id_utils.py +0 -27
- notionary/util/singleton.py +0 -18
- notionary/util/singleton_metaclass.py +0 -22
- notionary/workspace.py +0 -105
- notionary-0.2.27.dist-info/RECORD +0 -202
@@ -0,0 +1,353 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import asyncio
|
4
|
+
from collections.abc import AsyncIterator, Callable
|
5
|
+
from typing import TYPE_CHECKING, Self
|
6
|
+
|
7
|
+
from notionary.blocks.rich_text.rich_text_markdown_converter import RichTextToMarkdownConverter
|
8
|
+
from notionary.data_source.http.client import DataSourceClient
|
9
|
+
from notionary.data_source.http.data_source_instance_client import DataSourceInstanceClient
|
10
|
+
from notionary.data_source.properties.models import (
|
11
|
+
DataSourceMultiSelectProperty,
|
12
|
+
DataSourceProperty,
|
13
|
+
DataSourcePropertyOption,
|
14
|
+
DataSourcePropertyT,
|
15
|
+
DataSourceRelationProperty,
|
16
|
+
DataSourceSelectProperty,
|
17
|
+
DataSourceStatusProperty,
|
18
|
+
)
|
19
|
+
from notionary.data_source.query.builder import DataSourceQueryBuilder
|
20
|
+
from notionary.data_source.query.resolver import QueryResolver
|
21
|
+
from notionary.data_source.query.schema import (
|
22
|
+
DataSourceQueryParams,
|
23
|
+
)
|
24
|
+
from notionary.data_source.schemas import DataSourceDto
|
25
|
+
from notionary.exceptions.data_source.properties import DataSourcePropertyNotFound, DataSourcePropertyTypeError
|
26
|
+
from notionary.page.properties.models import PageTitleProperty
|
27
|
+
from notionary.page.schemas import NotionPageDto
|
28
|
+
from notionary.shared.entity.dto_parsers import (
|
29
|
+
extract_cover_image_url_from_dto,
|
30
|
+
extract_database_id,
|
31
|
+
extract_description,
|
32
|
+
extract_emoji_icon_from_dto,
|
33
|
+
extract_external_icon_url_from_dto,
|
34
|
+
extract_title,
|
35
|
+
)
|
36
|
+
from notionary.shared.entity.entity_metadata_update_client import EntityMetadataUpdateClient
|
37
|
+
from notionary.shared.entity.service import Entity
|
38
|
+
from notionary.user.schemas import PartialUserDto
|
39
|
+
from notionary.workspace.query.service import WorkspaceQueryService
|
40
|
+
|
41
|
+
if TYPE_CHECKING:
|
42
|
+
from notionary import NotionDatabase, NotionPage
|
43
|
+
|
44
|
+
|
45
|
+
class NotionDataSource(Entity):
|
46
|
+
def __init__(
|
47
|
+
self,
|
48
|
+
id: str,
|
49
|
+
title: str,
|
50
|
+
created_time: str,
|
51
|
+
created_by: PartialUserDto,
|
52
|
+
last_edited_time: str,
|
53
|
+
last_edited_by: PartialUserDto,
|
54
|
+
archived: bool,
|
55
|
+
in_trash: bool,
|
56
|
+
properties: dict[str, DataSourceProperty],
|
57
|
+
parent_database_id: str | None,
|
58
|
+
emoji_icon: str | None = None,
|
59
|
+
external_icon_url: str | None = None,
|
60
|
+
cover_image_url: str | None = None,
|
61
|
+
description: str | None = None,
|
62
|
+
data_source_instance_client: DataSourceInstanceClient | None = None,
|
63
|
+
query_resolver: QueryResolver | None = None,
|
64
|
+
) -> None:
|
65
|
+
super().__init__(
|
66
|
+
id=id,
|
67
|
+
created_time=created_time,
|
68
|
+
created_by=created_by,
|
69
|
+
last_edited_time=last_edited_time,
|
70
|
+
last_edited_by=last_edited_by,
|
71
|
+
in_trash=in_trash,
|
72
|
+
emoji_icon=emoji_icon,
|
73
|
+
external_icon_url=external_icon_url,
|
74
|
+
cover_image_url=cover_image_url,
|
75
|
+
)
|
76
|
+
self._parent_database_id = parent_database_id
|
77
|
+
self._parent_database: NotionDatabase | None = None
|
78
|
+
self._title = title
|
79
|
+
self._archived = archived
|
80
|
+
self._description = description
|
81
|
+
self._properties = properties or {}
|
82
|
+
self._data_source_client = data_source_instance_client or DataSourceInstanceClient(data_source_id=id)
|
83
|
+
self.query_resolver = query_resolver or QueryResolver()
|
84
|
+
|
85
|
+
@classmethod
|
86
|
+
async def from_id(
|
87
|
+
cls,
|
88
|
+
data_source_id: str,
|
89
|
+
data_source_client: DataSourceClient | None = None,
|
90
|
+
rich_text_converter: RichTextToMarkdownConverter | None = None,
|
91
|
+
) -> Self:
|
92
|
+
client = data_source_client or DataSourceClient()
|
93
|
+
converter = rich_text_converter or RichTextToMarkdownConverter()
|
94
|
+
data_source_dto = await client.get_data_source(data_source_id)
|
95
|
+
return await cls._create_from_dto(data_source_dto, converter)
|
96
|
+
|
97
|
+
@classmethod
|
98
|
+
async def from_title(
|
99
|
+
cls,
|
100
|
+
data_source_title: str,
|
101
|
+
min_similarity: float = 0.6,
|
102
|
+
search_service: WorkspaceQueryService | None = None,
|
103
|
+
) -> Self:
|
104
|
+
service = search_service or WorkspaceQueryService()
|
105
|
+
return await service.find_data_source(data_source_title, min_similarity=min_similarity)
|
106
|
+
|
107
|
+
@classmethod
|
108
|
+
async def _create_from_dto(
|
109
|
+
cls,
|
110
|
+
response: DataSourceDto,
|
111
|
+
rich_text_converter: RichTextToMarkdownConverter,
|
112
|
+
) -> Self:
|
113
|
+
title, description = await asyncio.gather(
|
114
|
+
extract_title(response, rich_text_converter),
|
115
|
+
extract_description(response, rich_text_converter),
|
116
|
+
)
|
117
|
+
|
118
|
+
parent_database_id = extract_database_id(response)
|
119
|
+
|
120
|
+
return cls._create(
|
121
|
+
id=response.id,
|
122
|
+
title=title,
|
123
|
+
description=description,
|
124
|
+
created_time=response.created_time,
|
125
|
+
created_by=response.created_by,
|
126
|
+
last_edited_time=response.last_edited_time,
|
127
|
+
last_edited_by=response.last_edited_by,
|
128
|
+
archived=response.archived,
|
129
|
+
in_trash=response.in_trash,
|
130
|
+
properties=response.properties,
|
131
|
+
parent_database_id=parent_database_id,
|
132
|
+
emoji_icon=extract_emoji_icon_from_dto(response),
|
133
|
+
external_icon_url=extract_external_icon_url_from_dto(response),
|
134
|
+
cover_image_url=extract_cover_image_url_from_dto(response),
|
135
|
+
)
|
136
|
+
|
137
|
+
@classmethod
|
138
|
+
def _create(
|
139
|
+
cls,
|
140
|
+
id: str,
|
141
|
+
title: str,
|
142
|
+
created_time: str,
|
143
|
+
created_by: PartialUserDto,
|
144
|
+
last_edited_time: str,
|
145
|
+
last_edited_by: PartialUserDto,
|
146
|
+
archived: bool,
|
147
|
+
in_trash: bool,
|
148
|
+
properties: dict[str, DataSourceProperty],
|
149
|
+
parent_database_id: str | None,
|
150
|
+
emoji_icon: str | None = None,
|
151
|
+
external_icon_url: str | None = None,
|
152
|
+
cover_image_url: str | None = None,
|
153
|
+
description: str | None = None,
|
154
|
+
) -> Self:
|
155
|
+
data_source_instance_client = DataSourceInstanceClient(data_source_id=id)
|
156
|
+
return cls(
|
157
|
+
id=id,
|
158
|
+
title=title,
|
159
|
+
created_time=created_time,
|
160
|
+
created_by=created_by,
|
161
|
+
last_edited_time=last_edited_time,
|
162
|
+
last_edited_by=last_edited_by,
|
163
|
+
archived=archived,
|
164
|
+
in_trash=in_trash,
|
165
|
+
parent_database_id=parent_database_id,
|
166
|
+
emoji_icon=emoji_icon,
|
167
|
+
external_icon_url=external_icon_url,
|
168
|
+
cover_image_url=cover_image_url,
|
169
|
+
description=description,
|
170
|
+
properties=properties,
|
171
|
+
data_source_instance_client=data_source_instance_client,
|
172
|
+
)
|
173
|
+
|
174
|
+
@property
|
175
|
+
def _entity_metadata_update_client(self) -> EntityMetadataUpdateClient:
|
176
|
+
return self._data_source_client
|
177
|
+
|
178
|
+
@property
|
179
|
+
def title(self) -> str:
|
180
|
+
return self._title
|
181
|
+
|
182
|
+
@property
|
183
|
+
def archived(self) -> bool:
|
184
|
+
return self._archived
|
185
|
+
|
186
|
+
@property
|
187
|
+
def description(self) -> str | None:
|
188
|
+
return self._description
|
189
|
+
|
190
|
+
@property
|
191
|
+
def properties(self) -> dict[str, DataSourceProperty]:
|
192
|
+
return self._properties
|
193
|
+
|
194
|
+
async def get_parent_database(self) -> NotionDatabase | None:
|
195
|
+
if self._parent_database is None and self._parent_database_id:
|
196
|
+
self._parent_database = await NotionDatabase.from_id(self._parent_database_id)
|
197
|
+
return self._parent_database
|
198
|
+
|
199
|
+
async def create_blank_page(self, title: str | None = None) -> NotionPage:
|
200
|
+
return await self._data_source_client.create_blank_page(title=title)
|
201
|
+
|
202
|
+
async def set_title(self, title: str) -> None:
|
203
|
+
data_source_dto = await self._data_source_client.update_title(title)
|
204
|
+
self._title = data_source_dto.title
|
205
|
+
|
206
|
+
async def archive(self) -> None:
|
207
|
+
if self._archived:
|
208
|
+
self.logger.info("Data source is already archived.")
|
209
|
+
return
|
210
|
+
await self._data_source_client.archive()
|
211
|
+
self._archived = True
|
212
|
+
|
213
|
+
async def unarchive(self) -> None:
|
214
|
+
if not self._archived:
|
215
|
+
self.logger.info("Data source is not archived.")
|
216
|
+
return
|
217
|
+
await self._data_source_client.unarchive()
|
218
|
+
self._archived = False
|
219
|
+
|
220
|
+
async def update_description(self, description: str) -> None:
|
221
|
+
self._description = await self._data_source_client.update_description(description)
|
222
|
+
|
223
|
+
async def get_options_for_property_by_name(self, property_name: str) -> list[str]:
|
224
|
+
prop = self._properties.get(property_name)
|
225
|
+
|
226
|
+
if prop is None:
|
227
|
+
return []
|
228
|
+
|
229
|
+
if isinstance(prop, DataSourceSelectProperty):
|
230
|
+
return prop.option_names
|
231
|
+
|
232
|
+
if isinstance(prop, DataSourceMultiSelectProperty):
|
233
|
+
return prop.option_names
|
234
|
+
|
235
|
+
if isinstance(prop, DataSourceStatusProperty):
|
236
|
+
return prop.option_names
|
237
|
+
|
238
|
+
if isinstance(prop, DataSourceRelationProperty):
|
239
|
+
return await self._get_relation_options(prop)
|
240
|
+
|
241
|
+
return []
|
242
|
+
|
243
|
+
def get_select_options_by_property_name(self, property_name: str) -> list[str]:
|
244
|
+
select_prop = self._get_typed_property_or_raise(property_name, DataSourceSelectProperty)
|
245
|
+
return select_prop.option_names
|
246
|
+
|
247
|
+
def get_multi_select_options_by_property_name(self, property_name: str) -> list[DataSourcePropertyOption]:
|
248
|
+
multi_select_prop = self._get_typed_property_or_raise(property_name, DataSourceMultiSelectProperty)
|
249
|
+
return multi_select_prop.option_names
|
250
|
+
|
251
|
+
def get_status_options_by_property_name(self, property_name: str) -> list[str]:
|
252
|
+
status_prop = self._get_typed_property_or_raise(property_name, DataSourceStatusProperty)
|
253
|
+
return status_prop.option_names
|
254
|
+
|
255
|
+
async def get_relation_options_by_property_name(self, property_name: str) -> list[str]:
|
256
|
+
relation_prop = self._get_typed_property_or_raise(property_name, DataSourceRelationProperty)
|
257
|
+
return await self._get_relation_options(relation_prop)
|
258
|
+
|
259
|
+
async def _get_relation_options(self, relation_prop: DataSourceRelationProperty) -> list[str]:
|
260
|
+
related_data_source_id = relation_prop.related_data_source_id
|
261
|
+
if not related_data_source_id:
|
262
|
+
return []
|
263
|
+
|
264
|
+
async with DataSourceInstanceClient(related_data_source_id) as related_client:
|
265
|
+
search_results = await related_client.query()
|
266
|
+
|
267
|
+
page_titles = []
|
268
|
+
for page_response in search_results.results:
|
269
|
+
title = self._extract_title_from_notion_page_dto(page_response)
|
270
|
+
if title:
|
271
|
+
page_titles.append(title)
|
272
|
+
|
273
|
+
return page_titles
|
274
|
+
|
275
|
+
def _extract_title_from_notion_page_dto(self, page: NotionPageDto) -> str | None:
|
276
|
+
if not page.properties:
|
277
|
+
return None
|
278
|
+
|
279
|
+
title_property = next(
|
280
|
+
(prop for prop in page.properties.values() if isinstance(prop, PageTitleProperty)),
|
281
|
+
None,
|
282
|
+
)
|
283
|
+
|
284
|
+
if not title_property:
|
285
|
+
return None
|
286
|
+
|
287
|
+
return "".join(item.plain_text for item in title_property.title)
|
288
|
+
|
289
|
+
def _get_typed_property_or_raise(self, name: str, property_type: type[DataSourcePropertyT]) -> DataSourcePropertyT:
|
290
|
+
prop = self._properties.get(name)
|
291
|
+
|
292
|
+
if prop is None:
|
293
|
+
raise DataSourcePropertyNotFound(
|
294
|
+
property_name=name,
|
295
|
+
available_properties=list(self._properties.keys()),
|
296
|
+
)
|
297
|
+
|
298
|
+
if not isinstance(prop, property_type):
|
299
|
+
raise DataSourcePropertyTypeError(
|
300
|
+
property_name=name, expected_type=property_type.__name__, actual_type=type(prop).__name__
|
301
|
+
)
|
302
|
+
|
303
|
+
return prop
|
304
|
+
|
305
|
+
def filter(self) -> DataSourceQueryBuilder:
|
306
|
+
return DataSourceQueryBuilder(properties=self._properties)
|
307
|
+
|
308
|
+
async def query(self, filter_fn: Callable[[DataSourceQueryBuilder], DataSourceQueryBuilder]) -> list[NotionPage]:
|
309
|
+
builder = DataSourceQueryBuilder(properties=self._properties)
|
310
|
+
filter_fn(builder)
|
311
|
+
query_params = builder.build()
|
312
|
+
|
313
|
+
return await self.get_pages(query_params)
|
314
|
+
|
315
|
+
async def query_stream(
|
316
|
+
self, filter_fn: Callable[[DataSourceQueryBuilder], DataSourceQueryBuilder]
|
317
|
+
) -> AsyncIterator[NotionPage]:
|
318
|
+
builder = DataSourceQueryBuilder(properties=self._properties)
|
319
|
+
filter_fn(builder)
|
320
|
+
query_params = builder.build()
|
321
|
+
|
322
|
+
async for page in self.get_pages_stream(query_params):
|
323
|
+
yield page
|
324
|
+
|
325
|
+
async def get_pages(
|
326
|
+
self,
|
327
|
+
query_params: DataSourceQueryParams | None = None,
|
328
|
+
) -> list[NotionPage]:
|
329
|
+
from notionary import NotionPage
|
330
|
+
|
331
|
+
resolved_params = await self._resolve_query_params_if_needed(query_params)
|
332
|
+
query_response = await self._data_source_client.query(query_params=resolved_params)
|
333
|
+
return [await NotionPage.from_id(page.id) for page in query_response.results]
|
334
|
+
|
335
|
+
async def get_pages_stream(
|
336
|
+
self,
|
337
|
+
query_params: DataSourceQueryParams | None = None,
|
338
|
+
) -> AsyncIterator[NotionPage]:
|
339
|
+
from notionary import NotionPage
|
340
|
+
|
341
|
+
resolved_params = await self._resolve_query_params_if_needed(query_params)
|
342
|
+
|
343
|
+
async for page in self._data_source_client.query_stream(query_params=resolved_params):
|
344
|
+
yield await NotionPage.from_id(page.id)
|
345
|
+
|
346
|
+
async def _resolve_query_params_if_needed(
|
347
|
+
self,
|
348
|
+
query_params: DataSourceQueryParams | None,
|
349
|
+
) -> DataSourceQueryParams | None:
|
350
|
+
if query_params is None:
|
351
|
+
return None
|
352
|
+
|
353
|
+
return await self.query_resolver.resolve_params(query_params)
|
notionary/database/client.py
CHANGED
@@ -1,148 +1,43 @@
|
|
1
|
-
from
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
NotionDatabaseResponse,
|
6
|
-
NotionDatabaseSearchResponse,
|
7
|
-
NotionPageResponse,
|
8
|
-
NotionQueryDatabaseResponse,
|
1
|
+
from notionary.blocks.rich_text.rich_text_markdown_converter import RichTextToMarkdownConverter
|
2
|
+
from notionary.database.schemas import (
|
3
|
+
NotionDatabaseDto,
|
4
|
+
NotionDatabaseUpdateDto,
|
9
5
|
)
|
6
|
+
from notionary.http.client import NotionHttpClient
|
10
7
|
|
11
8
|
|
12
|
-
class
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
"""
|
17
|
-
|
18
|
-
def __init__(self, token: Optional[str] = None, timeout: int = 30):
|
19
|
-
super().__init__(token, timeout)
|
20
|
-
|
21
|
-
async def create_database(
|
22
|
-
self,
|
23
|
-
title: str,
|
24
|
-
parent_page_id: Optional[str],
|
25
|
-
properties: Optional[Dict[str, Any]] = None,
|
26
|
-
) -> NotionDatabaseResponse:
|
27
|
-
"""
|
28
|
-
Creates a new database as child of the specified page.
|
29
|
-
"""
|
30
|
-
if properties is None:
|
31
|
-
properties = {"Name": {"title": {}}}
|
32
|
-
|
33
|
-
database_data = {
|
34
|
-
"parent": {"page_id": parent_page_id},
|
35
|
-
"title": [{"type": "text", "text": {"content": title}}],
|
36
|
-
"properties": properties,
|
37
|
-
}
|
38
|
-
|
39
|
-
response = await self.post("databases", database_data)
|
40
|
-
return NotionDatabaseResponse.model_validate(response)
|
41
|
-
|
42
|
-
async def get_database(self, database_id: str) -> NotionDatabaseResponse:
|
43
|
-
"""
|
44
|
-
Gets metadata for a Notion database by its ID.
|
45
|
-
"""
|
46
|
-
response = await self.get(f"databases/{database_id}")
|
47
|
-
return NotionDatabaseResponse.model_validate(response)
|
48
|
-
|
49
|
-
async def patch_database(
|
50
|
-
self, database_id: str, data: Dict[str, Any]
|
51
|
-
) -> NotionDatabaseResponse:
|
52
|
-
"""
|
53
|
-
Updates a Notion database with the provided data.
|
54
|
-
"""
|
55
|
-
response = await self.patch(f"databases/{database_id}", data=data)
|
56
|
-
return NotionDatabaseResponse.model_validate(response)
|
57
|
-
|
58
|
-
async def query_database(
|
59
|
-
self, database_id: str, query_data: Dict[str, Any] = None
|
60
|
-
) -> NotionQueryDatabaseResponse:
|
61
|
-
"""
|
62
|
-
Queries a Notion database with the provided filter and sorts.
|
63
|
-
"""
|
64
|
-
response = await self.post(f"databases/{database_id}/query", data=query_data)
|
65
|
-
return NotionQueryDatabaseResponse.model_validate(response)
|
9
|
+
class NotionDatabaseHttpClient(NotionHttpClient):
|
10
|
+
def __init__(self, database_id: str, timeout: int = 30) -> None:
|
11
|
+
super().__init__(timeout)
|
12
|
+
self._database_id = database_id
|
66
13
|
|
67
|
-
async def
|
68
|
-
|
69
|
-
|
70
|
-
"""
|
71
|
-
Queries a Notion database by title.
|
72
|
-
"""
|
73
|
-
query_data = {
|
74
|
-
"filter": {"property": "title", "title": {"contains": page_title}}
|
75
|
-
}
|
14
|
+
async def get_database(self) -> NotionDatabaseDto:
|
15
|
+
response = await self.get(f"databases/{self._database_id}")
|
16
|
+
return NotionDatabaseDto.model_validate(response)
|
76
17
|
|
77
|
-
|
18
|
+
async def patch_database(self, update_database_dto: NotionDatabaseUpdateDto) -> NotionDatabaseDto:
|
19
|
+
update_database_dto_dict = update_database_dto.model_dump(exclude_none=True)
|
78
20
|
|
79
|
-
|
80
|
-
|
81
|
-
) -> NotionDatabaseSearchResponse:
|
82
|
-
"""
|
83
|
-
Searches for databases in Notion using the search endpoint.
|
21
|
+
response = await self.patch(f"databases/{self._database_id}", data=update_database_dto_dict)
|
22
|
+
return NotionDatabaseDto.model_validate(response)
|
84
23
|
|
85
|
-
|
86
|
-
|
87
|
-
sort_ascending: Whether to sort in ascending order
|
88
|
-
limit: Maximum number of results to return
|
89
|
-
"""
|
90
|
-
search_data = {
|
91
|
-
"query": query,
|
92
|
-
"filter": {"value": "database", "property": "object"},
|
93
|
-
"sort": {
|
94
|
-
"direction": "ascending" if sort_ascending else "descending",
|
95
|
-
"timestamp": "last_edited_time",
|
96
|
-
},
|
97
|
-
"page_size": limit,
|
98
|
-
}
|
24
|
+
async def update_database_title(self, title: str) -> NotionDatabaseDto:
|
25
|
+
from notionary.blocks.rich_text.markdown_rich_text_converter import MarkdownRichTextConverter
|
99
26
|
|
100
|
-
|
101
|
-
|
27
|
+
markdown_rich_text_formatter = MarkdownRichTextConverter()
|
28
|
+
database_rich_text = await markdown_rich_text_formatter.to_rich_text(title)
|
102
29
|
|
103
|
-
|
104
|
-
|
105
|
-
Creates a new blank page in the given database with minimal properties.
|
106
|
-
"""
|
107
|
-
page_data = {
|
108
|
-
"parent": {"database_id": parent_database_id},
|
109
|
-
"properties": {},
|
110
|
-
}
|
111
|
-
response = await self.post("pages", page_data)
|
112
|
-
return NotionPageResponse.model_validate(response)
|
30
|
+
database_title_update_dto = NotionDatabaseUpdateDto(title=database_rich_text)
|
31
|
+
return await self.patch_database(database_title_update_dto)
|
113
32
|
|
114
|
-
async def
|
115
|
-
|
116
|
-
) -> NotionDatabaseResponse:
|
117
|
-
"""
|
118
|
-
Updates the title of a database.
|
119
|
-
"""
|
120
|
-
data = {"title": [{"text": {"content": title}}]}
|
121
|
-
return await self.patch_database(database_id, data)
|
33
|
+
async def update_database_description(self, description: str) -> str:
|
34
|
+
from notionary.blocks.rich_text.markdown_rich_text_converter import MarkdownRichTextConverter
|
122
35
|
|
123
|
-
|
124
|
-
|
125
|
-
) -> NotionDatabaseResponse:
|
126
|
-
"""
|
127
|
-
Updates the emoji/icon of a database.
|
128
|
-
"""
|
129
|
-
data = {"icon": {"type": "emoji", "emoji": emoji}}
|
130
|
-
return await self.patch_database(database_id, data)
|
36
|
+
markdown_to_rich_text_converter = MarkdownRichTextConverter()
|
37
|
+
rich_text_description = await markdown_to_rich_text_converter.to_rich_text(description)
|
131
38
|
|
132
|
-
|
133
|
-
|
134
|
-
) -> NotionDatabaseResponse:
|
135
|
-
"""
|
136
|
-
Updates the cover image of a database.
|
137
|
-
"""
|
138
|
-
data = {"cover": {"type": "external", "external": {"url": image_url}}}
|
139
|
-
return await self.patch_database(database_id, data)
|
39
|
+
database_description_update_dto = NotionDatabaseUpdateDto(description=rich_text_description)
|
40
|
+
update_database_response = await self.patch_database(database_description_update_dto)
|
140
41
|
|
141
|
-
|
142
|
-
|
143
|
-
) -> NotionDatabaseResponse:
|
144
|
-
"""
|
145
|
-
Updates the database icon with an external image URL.
|
146
|
-
"""
|
147
|
-
data = {"icon": {"type": "external", "external": {"url": icon_url}}}
|
148
|
-
return await self.patch_database(database_id, data)
|
42
|
+
rich_text_to_markdown_converter = RichTextToMarkdownConverter()
|
43
|
+
return await rich_text_to_markdown_converter.to_markdown(update_database_response.description)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from typing import override
|
2
|
+
|
3
|
+
from notionary.database.schemas import NotionDatabaseDto
|
4
|
+
from notionary.http.client import NotionHttpClient
|
5
|
+
from notionary.shared.entity.entity_metadata_update_client import EntityMetadataUpdateClient
|
6
|
+
from notionary.shared.entity.schemas import NotionEntityUpdateDto
|
7
|
+
|
8
|
+
|
9
|
+
class DatabaseMetadataUpdateClient(NotionHttpClient, EntityMetadataUpdateClient):
|
10
|
+
def __init__(self, database_id: str, timeout: int = 30) -> None:
|
11
|
+
super().__init__(timeout)
|
12
|
+
self._database_id = database_id
|
13
|
+
|
14
|
+
@override
|
15
|
+
async def patch_metadata(self, updated_data: NotionEntityUpdateDto) -> NotionDatabaseDto:
|
16
|
+
updated_data_dict = updated_data.model_dump(exclude_unset=True, exclude_none=True)
|
17
|
+
|
18
|
+
response_dict = await self.patch(f"databases/{self._database_id}", data=updated_data_dict)
|
19
|
+
return NotionDatabaseDto.model_validate(response_dict)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from pydantic import BaseModel, Field
|
2
|
+
|
3
|
+
from notionary.blocks.rich_text.models import RichText
|
4
|
+
from notionary.shared.entity.schemas import EntityResponseDto
|
5
|
+
from notionary.shared.models.cover import NotionCover
|
6
|
+
from notionary.shared.models.icon import Icon
|
7
|
+
|
8
|
+
|
9
|
+
class _DataSourceDiscoveryDto(BaseModel):
|
10
|
+
id: str
|
11
|
+
name: str
|
12
|
+
|
13
|
+
|
14
|
+
class NotionDatabaseDto(EntityResponseDto):
|
15
|
+
title: list[RichText]
|
16
|
+
description: list[RichText]
|
17
|
+
is_inline: bool
|
18
|
+
is_locked: bool
|
19
|
+
data_sources: list[_DataSourceDiscoveryDto] = Field(default_factory=list)
|
20
|
+
url: str
|
21
|
+
public_url: str | None = None
|
22
|
+
|
23
|
+
|
24
|
+
class NotionDatabaseUpdateDto(BaseModel):
|
25
|
+
title: list[RichText] | None = None
|
26
|
+
icon: Icon | None = None
|
27
|
+
cover: NotionCover | None = None
|
28
|
+
archived: bool | None = None
|
29
|
+
description: list[RichText] | None = None
|