notionary 0.2.26__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.26.dist-info → notionary-0.2.28.dist-info}/METADATA +54 -49
- notionary-0.2.28.dist-info/RECORD +200 -0
- {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info}/WHEEL +1 -1
- {notionary-0.2.26.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 -674
- 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.26.dist-info/RECORD +0 -202
@@ -0,0 +1,34 @@
|
|
1
|
+
import asyncio
|
2
|
+
|
3
|
+
from notionary.blocks.rich_text.markdown_rich_text_converter import MarkdownRichTextConverter
|
4
|
+
from notionary.comments.client import CommentClient
|
5
|
+
from notionary.comments.factory import CommentFactory
|
6
|
+
from notionary.comments.models import Comment
|
7
|
+
|
8
|
+
|
9
|
+
class CommentService:
|
10
|
+
def __init__(
|
11
|
+
self,
|
12
|
+
client: CommentClient | None = None,
|
13
|
+
factory: CommentFactory | None = None,
|
14
|
+
markdown_rich_text_converter: MarkdownRichTextConverter | None = None,
|
15
|
+
) -> None:
|
16
|
+
self.client = client or CommentClient()
|
17
|
+
self.factory = factory or CommentFactory()
|
18
|
+
self._converter = markdown_rich_text_converter or MarkdownRichTextConverter()
|
19
|
+
|
20
|
+
async def list_all_comments_for_page(self, page_id: str) -> list[Comment]:
|
21
|
+
comment_dtos = [dto async for dto in self.client.iter_comments(page_id)]
|
22
|
+
|
23
|
+
comments = await asyncio.gather(*(self.factory.create_from_dto(dto) for dto in comment_dtos))
|
24
|
+
return comments
|
25
|
+
|
26
|
+
async def create_comment_on_page(self, page_id: str, text: str) -> Comment:
|
27
|
+
rich_text = await self._converter.to_rich_text(text)
|
28
|
+
comment_dto = await self.client.create_comment_for_page(rich_text=rich_text, page_id=page_id)
|
29
|
+
return await self.factory.create_from_dto(comment_dto)
|
30
|
+
|
31
|
+
async def reply_to_discussion_by_id(self, discussion_id: str, text: str) -> Comment:
|
32
|
+
rich_text = await self._converter.to_rich_text(text)
|
33
|
+
comment_dto = await self.client.create_comment_for_discussion(rich_text=rich_text, discussion_id=discussion_id)
|
34
|
+
return await self.factory.create_from_dto(comment_dto)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
from notionary.data_source.schemas import DataSourceDto
|
2
|
+
from notionary.http.client import NotionHttpClient
|
3
|
+
|
4
|
+
|
5
|
+
class DataSourceClient(NotionHttpClient):
|
6
|
+
def __init__(self, timeout: int = 30) -> None:
|
7
|
+
super().__init__(timeout)
|
8
|
+
|
9
|
+
async def get_data_source(self, data_source_id: str) -> DataSourceDto:
|
10
|
+
response = await self.get(f"data_sources/{data_source_id}")
|
11
|
+
return DataSourceDto.model_validate(response)
|
@@ -0,0 +1,94 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from collections.abc import AsyncIterator
|
4
|
+
from typing import TYPE_CHECKING, Any, override
|
5
|
+
|
6
|
+
from notionary.blocks.rich_text.rich_text_markdown_converter import RichTextToMarkdownConverter
|
7
|
+
from notionary.data_source.query.schema import DataSourceQueryParams
|
8
|
+
from notionary.data_source.schemas import DataSourceDto, QueryDataSourceResponse, UpdateDataSourceDto
|
9
|
+
from notionary.http.client import NotionHttpClient
|
10
|
+
from notionary.page.schemas import NotionPageDto
|
11
|
+
from notionary.shared.entity.entity_metadata_update_client import EntityMetadataUpdateClient
|
12
|
+
from notionary.utils.pagination import paginate_notion_api, paginate_notion_api_generator
|
13
|
+
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from notionary import NotionPage
|
16
|
+
|
17
|
+
|
18
|
+
class DataSourceInstanceClient(NotionHttpClient, EntityMetadataUpdateClient):
|
19
|
+
def __init__(self, data_source_id: str, timeout: int = 30) -> None:
|
20
|
+
super().__init__(timeout)
|
21
|
+
self._data_source_id = data_source_id
|
22
|
+
|
23
|
+
@override
|
24
|
+
async def patch_metadata(self, update_data_source_dto: UpdateDataSourceDto) -> DataSourceDto:
|
25
|
+
update_data_source_dto_dict = update_data_source_dto.model_dump(exclude_none=True)
|
26
|
+
response = await self.patch(f"data_sources/{self._data_source_id}", data=update_data_source_dto_dict)
|
27
|
+
return DataSourceDto.model_validate(response)
|
28
|
+
|
29
|
+
async def update_title(self, title: str) -> DataSourceDto:
|
30
|
+
update_data_source_dto = UpdateDataSourceDto(title=title)
|
31
|
+
return await self.patch_metadata(update_data_source_dto)
|
32
|
+
|
33
|
+
async def archive(self) -> None:
|
34
|
+
update_data_source_dto = UpdateDataSourceDto(archived=True)
|
35
|
+
return await self.patch_metadata(update_data_source_dto)
|
36
|
+
|
37
|
+
async def unarchive(self) -> None:
|
38
|
+
update_data_source_dto = UpdateDataSourceDto(archived=False)
|
39
|
+
await self.patch_metadata(update_data_source_dto)
|
40
|
+
|
41
|
+
async def update_description(self, description: str) -> str:
|
42
|
+
from notionary.blocks.rich_text.markdown_rich_text_converter import MarkdownRichTextConverter
|
43
|
+
|
44
|
+
markdown_rich_text_converter = MarkdownRichTextConverter()
|
45
|
+
rich_text_description = await markdown_rich_text_converter.to_rich_text(description)
|
46
|
+
update_data_source_dto = UpdateDataSourceDto(description=rich_text_description)
|
47
|
+
|
48
|
+
updated_data_source_dto = await self.patch_metadata(update_data_source_dto)
|
49
|
+
|
50
|
+
markdown_rich_text_converter = RichTextToMarkdownConverter()
|
51
|
+
updated_markdown_description = (
|
52
|
+
await markdown_rich_text_converter.to_markdown(updated_data_source_dto.description)
|
53
|
+
if updated_data_source_dto.description
|
54
|
+
else None
|
55
|
+
)
|
56
|
+
return updated_markdown_description
|
57
|
+
|
58
|
+
async def query(self, query_params: DataSourceQueryParams | None = None) -> QueryDataSourceResponse:
|
59
|
+
query_params_dict = query_params.model_dump() if query_params else {}
|
60
|
+
all_results = await paginate_notion_api(self._make_query_request, query_data=query_params_dict or {})
|
61
|
+
|
62
|
+
return QueryDataSourceResponse(
|
63
|
+
results=all_results,
|
64
|
+
next_cursor=None,
|
65
|
+
has_more=False,
|
66
|
+
)
|
67
|
+
|
68
|
+
async def query_stream(self, query_params: DataSourceQueryParams | None = None) -> AsyncIterator[Any]:
|
69
|
+
query_params_dict = query_params.model_dump() if query_params else {}
|
70
|
+
|
71
|
+
async for result in paginate_notion_api_generator(self._make_query_request, query_data=query_params_dict or {}):
|
72
|
+
yield result
|
73
|
+
|
74
|
+
async def _make_query_request(
|
75
|
+
self, query_data: dict[str, Any], start_cursor: str | None = None
|
76
|
+
) -> QueryDataSourceResponse:
|
77
|
+
current_query_data = query_data.copy()
|
78
|
+
if start_cursor:
|
79
|
+
current_query_data["start_cursor"] = start_cursor
|
80
|
+
|
81
|
+
response = await self.post(f"data_sources/{self._data_source_id}/query", data=current_query_data)
|
82
|
+
return QueryDataSourceResponse.model_validate(response)
|
83
|
+
|
84
|
+
async def create_blank_page(self, title: str | None = None) -> NotionPage:
|
85
|
+
from notionary import NotionPage
|
86
|
+
|
87
|
+
data = {"parent": {"type": "data_source_id", "data_source_id": self._data_source_id}, "properties": {}}
|
88
|
+
|
89
|
+
if title:
|
90
|
+
data["properties"]["Name"] = {"title": [{"text": {"content": title}}]}
|
91
|
+
|
92
|
+
response = await self.post("pages", data=data)
|
93
|
+
page_creation_response = NotionPageDto.model_validate(response)
|
94
|
+
return await NotionPage.from_id(page_creation_response.id)
|
@@ -0,0 +1,406 @@
|
|
1
|
+
from enum import StrEnum
|
2
|
+
from typing import Annotated, Any, Literal, TypeVar
|
3
|
+
|
4
|
+
from pydantic import BaseModel, Field
|
5
|
+
|
6
|
+
from notionary.shared.properties.type import PropertyType
|
7
|
+
|
8
|
+
# ============================================================================
|
9
|
+
# Base Model
|
10
|
+
# ============================================================================
|
11
|
+
|
12
|
+
|
13
|
+
class DataSourceProperty(BaseModel):
|
14
|
+
id: str
|
15
|
+
name: str
|
16
|
+
description: str | None = None
|
17
|
+
type: PropertyType
|
18
|
+
|
19
|
+
|
20
|
+
# ============================================================================
|
21
|
+
# Enums and Shared Config Models
|
22
|
+
# ============================================================================
|
23
|
+
|
24
|
+
|
25
|
+
class PropertyColor(StrEnum):
|
26
|
+
DEFAULT = "default"
|
27
|
+
GRAY = "gray"
|
28
|
+
BROWN = "brown"
|
29
|
+
ORANGE = "orange"
|
30
|
+
YELLOW = "yellow"
|
31
|
+
GREEN = "green"
|
32
|
+
BLUE = "blue"
|
33
|
+
PURPLE = "purple"
|
34
|
+
PINK = "pink"
|
35
|
+
RED = "red"
|
36
|
+
|
37
|
+
|
38
|
+
class NumberFormat(StrEnum):
|
39
|
+
NUMBER = "number"
|
40
|
+
NUMBER_WITH_COMMAS = "number_with_commas"
|
41
|
+
PERCENT = "percent"
|
42
|
+
DOLLAR = "dollar"
|
43
|
+
AUSTRALIAN_DOLLAR = "australian_dollar"
|
44
|
+
CANADIAN_DOLLAR = "canadian_dollar"
|
45
|
+
SINGAPORE_DOLLAR = "singapore_dollar"
|
46
|
+
EURO = "euro"
|
47
|
+
POUND = "pound"
|
48
|
+
YEN = "yen"
|
49
|
+
RUBLE = "ruble"
|
50
|
+
RUPEE = "rupee"
|
51
|
+
WON = "won"
|
52
|
+
YUAN = "yuan"
|
53
|
+
REAL = "real"
|
54
|
+
LIRA = "lira"
|
55
|
+
RUPIAH = "rupiah"
|
56
|
+
FRANC = "franc"
|
57
|
+
HONG_KONG_DOLLAR = "hong_kong_dollar"
|
58
|
+
NEW_ZEALAND_DOLLAR = "new_zealand_dollar"
|
59
|
+
KRONA = "krona"
|
60
|
+
NORWEGIAN_KRONE = "norwegian_krone"
|
61
|
+
MEXICAN_PESO = "mexican_peso"
|
62
|
+
RAND = "rand"
|
63
|
+
NEW_TAIWAN_DOLLAR = "new_taiwan_dollar"
|
64
|
+
DANISH_KRONE = "danish_krone"
|
65
|
+
ZLOTY = "zloty"
|
66
|
+
BAHT = "baht"
|
67
|
+
FORINT = "forint"
|
68
|
+
KORUNA = "koruna"
|
69
|
+
SHEKEL = "shekel"
|
70
|
+
CHILEAN_PESO = "chilean_peso"
|
71
|
+
PHILIPPINE_PESO = "philippine_peso"
|
72
|
+
DIRHAM = "dirham"
|
73
|
+
COLOMBIAN_PESO = "colombian_peso"
|
74
|
+
RIYAL = "riyal"
|
75
|
+
RINGGIT = "ringgit"
|
76
|
+
LEU = "leu"
|
77
|
+
ARGENTINE_PESO = "argentine_peso"
|
78
|
+
URUGUAYAN_PESO = "uruguayan_peso"
|
79
|
+
PERUVIAN_SOL = "peruvian_sol"
|
80
|
+
|
81
|
+
|
82
|
+
class RelationType(StrEnum):
|
83
|
+
SINGLE_PROPERTY = "single_property"
|
84
|
+
DUAL_PROPERTY = "dual_property"
|
85
|
+
|
86
|
+
|
87
|
+
class RollupFunction(StrEnum):
|
88
|
+
AVERAGE = "average"
|
89
|
+
CHECKED = "checked"
|
90
|
+
COUNT_PER_GROUP = "count_per_group"
|
91
|
+
COUNT = "count"
|
92
|
+
COUNT_VALUES = "count_values"
|
93
|
+
DATE_RANGE = "date_range"
|
94
|
+
EARLIEST_DATE = "earliest_date"
|
95
|
+
EMPTY = "empty"
|
96
|
+
LATEST_DATE = "latest_date"
|
97
|
+
MAX = "max"
|
98
|
+
MEDIAN = "median"
|
99
|
+
MIN = "min"
|
100
|
+
NOT_EMPTY = "not_empty"
|
101
|
+
PERCENT_CHECKED = "percent_checked"
|
102
|
+
PERCENT_EMPTY = "percent_empty"
|
103
|
+
PERCENT_NOT_EMPTY = "percent_not_empty"
|
104
|
+
PERCENT_PER_GROUP = "percent_per_group"
|
105
|
+
PERCENT_UNCHECKED = "percent_unchecked"
|
106
|
+
RANGE = "range"
|
107
|
+
UNCHECKED = "unchecked"
|
108
|
+
UNIQUE = "unique"
|
109
|
+
SHOW_ORIGINAL = "show_original"
|
110
|
+
SHOW_UNIQUE = "show_unique"
|
111
|
+
SUM = "sum"
|
112
|
+
|
113
|
+
|
114
|
+
class DataSourcePropertyOption(BaseModel):
|
115
|
+
id: str
|
116
|
+
name: str
|
117
|
+
color: PropertyColor
|
118
|
+
description: str | None = None
|
119
|
+
|
120
|
+
|
121
|
+
class DataSourceStatusGroup(BaseModel):
|
122
|
+
id: str
|
123
|
+
name: str
|
124
|
+
color: PropertyColor
|
125
|
+
option_ids: list[str]
|
126
|
+
|
127
|
+
|
128
|
+
# ============================================================================
|
129
|
+
# Config Models
|
130
|
+
# ============================================================================
|
131
|
+
|
132
|
+
|
133
|
+
class DataSourceStatusConfig(BaseModel):
|
134
|
+
options: list[DataSourcePropertyOption] = Field(default_factory=list)
|
135
|
+
groups: list[DataSourceStatusGroup] = Field(default_factory=list)
|
136
|
+
|
137
|
+
|
138
|
+
class DataSourceSelectConfig(BaseModel):
|
139
|
+
options: list[DataSourcePropertyOption] = Field(default_factory=list)
|
140
|
+
|
141
|
+
|
142
|
+
class DataSourceMultiSelectConfig(BaseModel):
|
143
|
+
options: list[DataSourcePropertyOption] = Field(default_factory=list)
|
144
|
+
|
145
|
+
|
146
|
+
class DataSourceRelationConfig(BaseModel):
|
147
|
+
database_id: str | None = None
|
148
|
+
data_source_id: str | None = None
|
149
|
+
type: RelationType = RelationType.SINGLE_PROPERTY
|
150
|
+
single_property: dict[str, Any] = Field(default_factory=dict)
|
151
|
+
|
152
|
+
|
153
|
+
class DataSourceNumberConfig(BaseModel):
|
154
|
+
format: NumberFormat
|
155
|
+
|
156
|
+
|
157
|
+
class DataSourceFormulaConfig(BaseModel):
|
158
|
+
expression: str
|
159
|
+
|
160
|
+
|
161
|
+
class DataSourceUniqueIdConfig(BaseModel):
|
162
|
+
prefix: str | None = None
|
163
|
+
|
164
|
+
|
165
|
+
class DataSourceRollupConfig(BaseModel):
|
166
|
+
function: RollupFunction
|
167
|
+
relation_property_id: str
|
168
|
+
relation_property_name: str
|
169
|
+
rollup_property_id: str
|
170
|
+
rollup_property_name: str
|
171
|
+
|
172
|
+
|
173
|
+
class DataSourceDateConfig(BaseModel): ...
|
174
|
+
|
175
|
+
|
176
|
+
class DataSourceCreatedTimeConfig(BaseModel): ...
|
177
|
+
|
178
|
+
|
179
|
+
class DataSourceCreatedByConfig(BaseModel): ...
|
180
|
+
|
181
|
+
|
182
|
+
class DataSourceLastEditedTimeConfig(BaseModel): ...
|
183
|
+
|
184
|
+
|
185
|
+
class DataSourceLastEditedByConfig(BaseModel): ...
|
186
|
+
|
187
|
+
|
188
|
+
class DataSourceLastVisitedTimeConfig(BaseModel): ...
|
189
|
+
|
190
|
+
|
191
|
+
class DataSourceTitleConfig(BaseModel): ...
|
192
|
+
|
193
|
+
|
194
|
+
class DataSourceRichTextConfig(BaseModel): ...
|
195
|
+
|
196
|
+
|
197
|
+
class DataSourceURLConfig(BaseModel): ...
|
198
|
+
|
199
|
+
|
200
|
+
class DataSourcePeopleConfig(BaseModel): ...
|
201
|
+
|
202
|
+
|
203
|
+
class DataSourceCheckboxConfig(BaseModel): ...
|
204
|
+
|
205
|
+
|
206
|
+
class DataSourceEmailConfig(BaseModel): ...
|
207
|
+
|
208
|
+
|
209
|
+
class DataSourcePhoneNumberConfig(BaseModel): ...
|
210
|
+
|
211
|
+
|
212
|
+
class DataSourceFilesConfig(BaseModel): ...
|
213
|
+
|
214
|
+
|
215
|
+
class DataSourceButtonConfig(BaseModel): ...
|
216
|
+
|
217
|
+
|
218
|
+
class DataSourceLocationConfig(BaseModel): ...
|
219
|
+
|
220
|
+
|
221
|
+
class DataSourceVerificationConfig(BaseModel): ...
|
222
|
+
|
223
|
+
|
224
|
+
class DataSourcePlaceConfig(BaseModel): ...
|
225
|
+
|
226
|
+
|
227
|
+
# ============================================================================
|
228
|
+
# Property Models
|
229
|
+
# ============================================================================
|
230
|
+
|
231
|
+
|
232
|
+
class DataSourceStatusProperty(DataSourceProperty):
|
233
|
+
type: Literal[PropertyType.STATUS] = PropertyType.STATUS
|
234
|
+
status: DataSourceStatusConfig = Field(default_factory=DataSourceStatusConfig)
|
235
|
+
|
236
|
+
@property
|
237
|
+
def option_names(self) -> list[str]:
|
238
|
+
return [option.name for option in self.status.options]
|
239
|
+
|
240
|
+
@property
|
241
|
+
def group_names(self) -> list[str]:
|
242
|
+
return [group.name for group in self.status.groups]
|
243
|
+
|
244
|
+
|
245
|
+
class DataSourceSelectProperty(DataSourceProperty):
|
246
|
+
type: Literal[PropertyType.SELECT] = PropertyType.SELECT
|
247
|
+
select: DataSourceSelectConfig = Field(default_factory=DataSourceSelectConfig)
|
248
|
+
|
249
|
+
@property
|
250
|
+
def option_names(self) -> list[str]:
|
251
|
+
return [option.name for option in self.select.options]
|
252
|
+
|
253
|
+
|
254
|
+
class DataSourceMultiSelectProperty(DataSourceProperty):
|
255
|
+
type: Literal[PropertyType.MULTI_SELECT] = PropertyType.MULTI_SELECT
|
256
|
+
multi_select: DataSourceMultiSelectConfig = Field(default_factory=DataSourceMultiSelectConfig)
|
257
|
+
|
258
|
+
@property
|
259
|
+
def option_names(self) -> list[str]:
|
260
|
+
return [option.name for option in self.multi_select.options]
|
261
|
+
|
262
|
+
|
263
|
+
class DataSourceRelationProperty(DataSourceProperty):
|
264
|
+
type: Literal[PropertyType.RELATION] = PropertyType.RELATION
|
265
|
+
relation: DataSourceRelationConfig = Field(default_factory=DataSourceRelationConfig)
|
266
|
+
|
267
|
+
@property
|
268
|
+
def related_database_id(self) -> str | None:
|
269
|
+
return self.relation.database_id
|
270
|
+
|
271
|
+
@property
|
272
|
+
def related_data_source_id(self) -> str | None:
|
273
|
+
return self.relation.data_source_id
|
274
|
+
|
275
|
+
|
276
|
+
class DataSourceDateProperty(DataSourceProperty):
|
277
|
+
type: Literal[PropertyType.DATE] = PropertyType.DATE
|
278
|
+
date: DataSourceDateConfig = Field(default_factory=DataSourceDateConfig)
|
279
|
+
|
280
|
+
|
281
|
+
class DataSourceCreatedTimeProperty(DataSourceProperty):
|
282
|
+
type: Literal[PropertyType.CREATED_TIME] = PropertyType.CREATED_TIME
|
283
|
+
created_time: DataSourceCreatedTimeConfig = Field(default_factory=DataSourceCreatedTimeConfig)
|
284
|
+
|
285
|
+
|
286
|
+
class DataSourceCreatedByProperty(DataSourceProperty):
|
287
|
+
type: Literal[PropertyType.CREATED_BY] = PropertyType.CREATED_BY
|
288
|
+
created_by: DataSourceCreatedByConfig = Field(default_factory=DataSourceCreatedByConfig)
|
289
|
+
|
290
|
+
|
291
|
+
class DataSourceLastEditedTimeProperty(DataSourceProperty):
|
292
|
+
type: Literal[PropertyType.LAST_EDITED_TIME] = PropertyType.LAST_EDITED_TIME
|
293
|
+
last_edited_time: DataSourceLastEditedTimeConfig = Field(default_factory=DataSourceLastEditedTimeConfig)
|
294
|
+
|
295
|
+
|
296
|
+
class DataSourceLastEditedByProperty(DataSourceProperty):
|
297
|
+
type: Literal[PropertyType.LAST_EDITED_BY] = PropertyType.LAST_EDITED_BY
|
298
|
+
last_edited_by: DataSourceLastEditedByConfig = Field(default_factory=DataSourceLastEditedByConfig)
|
299
|
+
|
300
|
+
|
301
|
+
class DataSourceTitleProperty(DataSourceProperty):
|
302
|
+
type: Literal[PropertyType.TITLE] = PropertyType.TITLE
|
303
|
+
title: DataSourceTitleConfig = Field(default_factory=DataSourceTitleConfig)
|
304
|
+
|
305
|
+
|
306
|
+
class DataSourceRichTextProperty(DataSourceProperty):
|
307
|
+
type: Literal[PropertyType.RICH_TEXT] = PropertyType.RICH_TEXT
|
308
|
+
rich_text: DataSourceRichTextConfig = Field(default_factory=DataSourceRichTextConfig)
|
309
|
+
|
310
|
+
|
311
|
+
class DataSourceURLProperty(DataSourceProperty):
|
312
|
+
type: Literal[PropertyType.URL] = PropertyType.URL
|
313
|
+
url: DataSourceURLConfig = Field(default_factory=DataSourceURLConfig)
|
314
|
+
|
315
|
+
|
316
|
+
class DataSourcePeopleProperty(DataSourceProperty):
|
317
|
+
type: Literal[PropertyType.PEOPLE] = PropertyType.PEOPLE
|
318
|
+
people: DataSourcePeopleConfig = Field(default_factory=DataSourcePeopleConfig)
|
319
|
+
|
320
|
+
|
321
|
+
class DataSourceNumberProperty(DataSourceProperty):
|
322
|
+
type: Literal[PropertyType.NUMBER] = PropertyType.NUMBER
|
323
|
+
number: DataSourceNumberConfig
|
324
|
+
|
325
|
+
@property
|
326
|
+
def number_format(self) -> NumberFormat:
|
327
|
+
return self.number.format
|
328
|
+
|
329
|
+
|
330
|
+
class DataSourceCheckboxProperty(DataSourceProperty):
|
331
|
+
type: Literal[PropertyType.CHECKBOX] = PropertyType.CHECKBOX
|
332
|
+
checkbox: DataSourceCheckboxConfig = Field(default_factory=DataSourceCheckboxConfig)
|
333
|
+
|
334
|
+
|
335
|
+
class DataSourceEmailProperty(DataSourceProperty):
|
336
|
+
type: Literal[PropertyType.EMAIL] = PropertyType.EMAIL
|
337
|
+
email: DataSourceEmailConfig = Field(default_factory=DataSourceEmailConfig)
|
338
|
+
|
339
|
+
|
340
|
+
class DataSourcePhoneNumberProperty(DataSourceProperty):
|
341
|
+
type: Literal[PropertyType.PHONE_NUMBER] = PropertyType.PHONE_NUMBER
|
342
|
+
phone_number: DataSourcePhoneNumberConfig = Field(default_factory=DataSourcePhoneNumberConfig)
|
343
|
+
|
344
|
+
|
345
|
+
class DataSourceFilesProperty(DataSourceProperty):
|
346
|
+
type: Literal[PropertyType.FILES] = PropertyType.FILES
|
347
|
+
files: DataSourceFilesConfig = Field(default_factory=DataSourceFilesConfig)
|
348
|
+
|
349
|
+
|
350
|
+
class DataSourceFormulaProperty(DataSourceProperty):
|
351
|
+
type: Literal[PropertyType.FORMULA] = PropertyType.FORMULA
|
352
|
+
formula: DataSourceFormulaConfig
|
353
|
+
|
354
|
+
@property
|
355
|
+
def expression(self) -> str:
|
356
|
+
return self.formula.expression
|
357
|
+
|
358
|
+
|
359
|
+
class DataSourceRollupProperty(DataSourceProperty):
|
360
|
+
type: Literal[PropertyType.ROLLUP] = PropertyType.ROLLUP
|
361
|
+
rollup: DataSourceRollupConfig
|
362
|
+
|
363
|
+
@property
|
364
|
+
def rollup_function(self) -> RollupFunction:
|
365
|
+
return self.rollup.function
|
366
|
+
|
367
|
+
|
368
|
+
class DataSourceUniqueIdProperty(DataSourceProperty):
|
369
|
+
type: Literal[PropertyType.UNIQUE_ID] = PropertyType.UNIQUE_ID
|
370
|
+
unique_id: DataSourceUniqueIdConfig = Field(default_factory=DataSourceUniqueIdConfig)
|
371
|
+
|
372
|
+
@property
|
373
|
+
def prefix(self) -> str | None:
|
374
|
+
return self.unique_id.prefix
|
375
|
+
|
376
|
+
|
377
|
+
# ============================================================================
|
378
|
+
# Discriminated Union
|
379
|
+
# ============================================================================
|
380
|
+
|
381
|
+
DiscriminatedDataSourceProperty = Annotated[
|
382
|
+
DataSourceStatusProperty
|
383
|
+
| DataSourceSelectProperty
|
384
|
+
| DataSourceMultiSelectProperty
|
385
|
+
| DataSourceRelationProperty
|
386
|
+
| DataSourceDateProperty
|
387
|
+
| DataSourceCreatedTimeProperty
|
388
|
+
| DataSourceCreatedByProperty
|
389
|
+
| DataSourceLastEditedTimeProperty
|
390
|
+
| DataSourceLastEditedByProperty
|
391
|
+
| DataSourceTitleProperty
|
392
|
+
| DataSourceRichTextProperty
|
393
|
+
| DataSourceURLProperty
|
394
|
+
| DataSourcePeopleProperty
|
395
|
+
| DataSourceNumberProperty
|
396
|
+
| DataSourceCheckboxProperty
|
397
|
+
| DataSourceEmailProperty
|
398
|
+
| DataSourcePhoneNumberProperty
|
399
|
+
| DataSourceFilesProperty
|
400
|
+
| DataSourceFormulaProperty
|
401
|
+
| DataSourceRollupProperty
|
402
|
+
| DataSourceUniqueIdProperty,
|
403
|
+
Field(discriminator="type"),
|
404
|
+
]
|
405
|
+
|
406
|
+
DataSourcePropertyT = TypeVar("DataSourcePropertyT", bound=DataSourceProperty)
|