notionary 0.1.16__py3-none-any.whl → 0.1.18__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.
@@ -217,6 +217,26 @@ class NotionDatabase(LoggingMixin):
217
217
  self.logger.error("Error in delete_page: %s", str(e))
218
218
  return {"success": False, "message": f"Error: {str(e)}"}
219
219
 
220
+ async def get_last_edited_time(self) -> Optional[str]:
221
+ """
222
+ Retrieve the last edited time of the database.
223
+
224
+ Returns:
225
+ ISO 8601 timestamp string of the last database edit, or None if request fails
226
+ """
227
+ try:
228
+ response = await self._client.get(f"databases/{self.database_id}")
229
+
230
+ if response and "last_edited_time" in response:
231
+ return response["last_edited_time"]
232
+
233
+ self.logger.warning("Could not retrieve last_edited_time for database %s", self.database_id)
234
+ return None
235
+
236
+ except Exception as e:
237
+ self.logger.error("Error fetching last_edited_time: %s", str(e))
238
+ return None
239
+
220
240
  async def close(self) -> None:
221
241
  """Close the client connection."""
222
242
  await self._client.close()
@@ -39,8 +39,7 @@ class PageContentManager(LoggingMixin):
39
39
  """
40
40
  try:
41
41
  blocks = self._markdown_to_notion_converter.convert(markdown_text)
42
- print(json.dumps(blocks, indent=4))
43
-
42
+
44
43
  fixed_blocks = self._chunker.fix_blocks_content_length(blocks)
45
44
 
46
45
  result = await self._client.patch(
@@ -173,5 +172,4 @@ class PageContentManager(LoggingMixin):
173
172
 
174
173
  async def get_text(self) -> str:
175
174
  blocks = await self.get_page_blocks_with_children()
176
- print(json.dumps(blocks, indent=4))
177
175
  return self._notion_to_markdown_converter.convert(blocks)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: notionary
3
- Version: 0.1.16
3
+ Version: 0.1.18
4
4
  Summary: A toolkit to convert between Markdown and Notion blocks
5
5
  Home-page: https://github.com/mathisarends/notionary
6
6
  Author: Mathis Arends
@@ -33,12 +33,14 @@ Dynamic: summary
33
33
  [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
34
34
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
35
35
 
36
- **Notionary** is a powerful Python library for interacting with the Notion API, making it easy to create, update, and manage Notion pages and databases programmatically with a clean, intuitive interface.
36
+ **Notionary** is a powerful Python library for interacting with the Notion API, making it easy to create, update, and manage Notion pages and databases programmatically with a clean, intuitive interface. It's specifically designed to be the foundation for AI-driven Notion content generation.
37
37
 
38
38
  ## Features
39
39
 
40
- - **Rich Markdown Support**: Write Notion pages using intuitive Markdown syntax with custom extensions
40
+ - **Rich Markdown Support**: Create Notion pages using intuitive Markdown syntax with custom extensions
41
41
  - **Dynamic Database Operations**: Create, update, and query database entries with schema auto-detection
42
+ - **Extensible Block Registry**: Add, customize, or remove Notion block elements with a flexible registry pattern
43
+ - **LLM-Ready Prompts**: Generate system prompts explaining Markdown syntax for LLMs to create Notion content
42
44
  - **Async-First Design**: Built for modern Python with full async/await support
43
45
  - **Schema-Based Validation**: Automatic property validation based on database schemas
44
46
  - **Intelligent Content Conversion**: Bidirectional conversion between Markdown and Notion blocks
@@ -56,7 +58,7 @@ Notionary extends standard Markdown with special syntax to support Notion-specif
56
58
  ### Text Formatting
57
59
 
58
60
  - Standard Markdown: `**bold**`, `*italic*`, `~~strikethrough~~`, `` `code` ``
59
- - Highlights: `==highlighted text==`, `==red warning==`, `==blue==`
61
+ - Highlights: `==highlighted text==`, `==red:warning==`, `==blue:note==`
60
62
 
61
63
  ### Block Elements
62
64
 
@@ -111,50 +113,43 @@ Notionary makes it easy to work with Notion databases, automatically handling sc
111
113
 
112
114
  ```python
113
115
  import asyncio
114
- from notionary.core.database.notion_database_manager import NotionDatabaseManager
116
+ from notionary import NotionDatabaseFactory
115
117
 
116
118
  async def main():
117
- database_id = "1a6389d5-7bd3-8097-aa38-e93cb052615a"
118
- db = NotionDatabaseManager(database_id)
119
- await db.initialize()
119
+ # Find database by name with fuzzy matching
120
+ db_manager = await NotionDatabaseFactory.from_database_name("Projects")
120
121
 
122
+ # Create a new page with properties
121
123
  properties = {
122
124
  "Title": "Created via Notionary",
123
- "Description": "This entry was created using Notionary.",
124
125
  "Status": "In Progress",
125
126
  "Priority": "High"
126
127
  }
127
128
 
128
- result = await db.create_page(properties)
129
+ page = await db_manager.create_blank_page()
129
130
 
130
- if result["success"]:
131
- page_id = result["page_id"]
132
- await db.update_page(page_id, {"Status": "Completed"})
131
+ # Set page content with rich Markdown
132
+ await page.set_title("My New Project")
133
+ await page.set_page_icon(emoji="🚀")
133
134
 
134
- filter_conditions = {
135
- "property": "Status",
136
- "status": {"equals": "Completed"}
137
- }
135
+ markdown = """
136
+ # Project Overview
138
137
 
139
- pages = await db.get_pages(limit=10, filter_conditions=filter_conditions)
138
+ !> [💡] This page was created programmatically using Notionary.
140
139
 
141
- await db.close()
140
+ ## Tasks
141
+ - [ ] Define project scope
142
+ - [ ] Create timeline
143
+ - [ ] Assign resources
142
144
 
143
- if __name__ == "__main__":
144
- asyncio.run(main())
145
- ```
146
-
147
- ## Finding Databases by Name
148
-
149
- Use fuzzy matching to find databases:
145
+ +++ Implementation Details
146
+ This project will use our standard architecture with custom extensions.
147
+ """
150
148
 
151
- ```python
152
- from notionary.core.database.notion_database_manager_factory import NotionDatabaseFactory
149
+ await page.replace_content(markdown)
153
150
 
154
- async def main():
155
- db_manager = await NotionDatabaseFactory.from_database_name("Projects")
156
- print(f"Found database: {db_manager.title}")
157
- await db_manager.close()
151
+ if __name__ == "__main__":
152
+ asyncio.run(main())
158
153
  ```
159
154
 
160
155
  ## Page Content Management
@@ -162,11 +157,11 @@ async def main():
162
157
  Create rich Notion pages using enhanced Markdown:
163
158
 
164
159
  ```python
165
- from notionary.core.page.notion_page_manager import NotionPageManager
160
+ from notionary import NotionPage
166
161
 
167
162
  async def create_rich_page():
168
163
  url = "https://www.notion.so/Your-Page-1cd389d57bd381e58be9d35ce24adf3d"
169
- page_manager = NotionPageManager(url=url)
164
+ page_manager = NotionPage(url=url)
170
165
 
171
166
  await page_manager.set_title("Notionary Demo")
172
167
  await page_manager.set_page_icon(emoji="✨")
@@ -190,20 +185,71 @@ async def create_rich_page():
190
185
  await page_manager.replace_content(markdown)
191
186
  ```
192
187
 
193
- ## Perfect for AI Agents and Automation
188
+ ## Block Registry & Builder
194
189
 
195
- - **Dynamic Content Generation**: AI agents can generate content in Markdown and render it as Notion pages
196
- - **Schema-Aware Operations**: Automatically validate and format properties
197
- - **Simplified API**: Easier integration with AI workflows
190
+ Notionary uses a flexible registry pattern with a builder to customize which Notion elements are supported, allowing programmatic creation of complex UI layouts that were previously only possible through Notion's UI:
191
+
192
+ ```python
193
+ from notionary import NotionPage
194
+ from notionary.elements.block_element_registry_builder import BlockElementRegistryBuilder
195
+
196
+ # Create a registry with standard Notion elements
197
+ registry = BlockElementRegistryBuilder.create_standard_registry()
198
+
199
+ # Or build a custom registry with only the elements you need
200
+ custom_registry = (
201
+ BlockElementRegistryBuilder()
202
+ .with_headings()
203
+ .with_callouts()
204
+ .with_toggles()
205
+ .with_lists()
206
+ .with_tables()
207
+ .with_paragraphs()
208
+ .build()
209
+ )
210
+
211
+ # Apply this registry to a page to enable custom Markdown support
212
+ page = NotionPage(url="https://www.notion.so/your-page-url")
213
+ page.block_registry = custom_registry
214
+
215
+ # Now your page supports exactly the elements you've defined
216
+ await page.replace_content("# Custom heading with only selected elements")
217
+ ```
218
+
219
+ This registry approach gives you granular control over which Notion UI elements can be created through Markdown, making it possible to programmatically construct any page layout that would normally require manual UI interaction.
220
+
221
+ ## AI-Ready LLM Prompt Generation
222
+
223
+ Notionary can automatically generate comprehensive system prompts for LLMs to understand Notion's custom Markdown syntax:
224
+
225
+ ```python
226
+ from notionary.elements.block_element_registry_builder import BlockElementRegistryBuilder
227
+
228
+ registry = BlockElementRegistryBuilder.create_standard_registry()
229
+ llm_system_prompt = registry.generate_llm_prompt()
230
+
231
+ # Use this prompt with your LLM to generate Notion-compatible Markdown
232
+ print(llm_system_prompt)
233
+ ```
234
+
235
+ This makes Notionary the perfect foundation for AI-driven Notion content generation, enabling LLMs to create properly formatted Notion pages.
198
236
 
199
237
  ## Examples
200
238
 
201
- See the `examples` folder for:
239
+ See the [examples folder](examples/) for more comprehensive demonstrations:
240
+
241
+ - [Database discovery and querying](examples/database_discovery_example.py)
242
+ - [Rich page creation with Markdown](examples/page_example.py)
243
+ - [Database factory usage](examples/database_factory_example.py)
244
+ - [Page lookup and access](examples/page_factory_by_url_example.py)
245
+ - [Iterating through database entries](examples/iter_database_example.py)
246
+
247
+ ## Perfect for AI Agents and Automation
202
248
 
203
- - Database discovery and querying
204
- - Rich page creation with Markdown
205
- - Entry management
206
- - Metadata manipulation
249
+ - **LLM Integration**: Generate Notion-compatible content with LLMs using the system prompt generator
250
+ - **Dynamic Content Generation**: AI agents can generate content in Markdown and render it as Notion pages
251
+ - **Schema-Aware Operations**: Automatically validate and format properties
252
+ - **Simplified API**: Easier integration with AI workflows
207
253
 
208
254
  ## License
209
255
 
@@ -2,7 +2,7 @@ notionary/__init__.py,sha256=sVqdwzMQcc9jf6FKi1qflilsx8rnWzluVhWewVi5gyI,717
2
2
  notionary/notion_client.py,sha256=NPPK7zId6EaC-hQeFJ7geaiROGtZfmc8cVP2nQez5DU,6040
3
3
  notionary/database/database_discovery.py,sha256=qDGFhXG9s-_6CXdRg8tMiwX4dvX7jLjgAUFPSNlYtlI,4506
4
4
  notionary/database/database_info_service.py,sha256=Ig6gx8jUSPYORJvfgEV5kV6t72pZQsWU8HPMqd43B-o,1336
5
- notionary/database/notion_database.py,sha256=RY5MlXNE5DVNWLC_Derljsz87ZMHkE-05Vgm80kvLxg,7250
5
+ notionary/database/notion_database.py,sha256=Zm5Ev0n4idKUe3ms8l3B4fyIezNNCCEDWHZ5vDoTknQ,7985
6
6
  notionary/database/notion_database_factory.py,sha256=Af57yaUHidD8TKJ8uyXOc2nnqHm7on6VGFdDRjxiq9o,6692
7
7
  notionary/database/models/page_result.py,sha256=Vmm5_oYpYAkIIJVoTd1ZZGloeC3cmFLMYP255mAmtaw,233
8
8
  notionary/elements/audio_element.py,sha256=XLARz5zlPPW_Qof6uhcYXFmyYzyS1fLdxdfsvh6GMOs,5589
@@ -33,7 +33,7 @@ notionary/page/notion_page.py,sha256=KIjVeiMJGWWxR6ty1uuNvMoQf2IoRmSUxwMdDIyOu40
33
33
  notionary/page/notion_page_factory.py,sha256=UUEZ-cyEWL0OMVPrgjc4vJdcplEa1bO2yHCYooACYC8,8189
34
34
  notionary/page/notion_to_markdown_converter.py,sha256=WHrESgMZPqnp3kufi0YB7Cyy8U1rwhJ0d4HHdBRfRdU,8053
35
35
  notionary/page/content/notion_page_content_chunker.py,sha256=xRks74Dqec-De6-AVTxMPnXs-MSJBzSm1HfJfaHiKr8,3330
36
- notionary/page/content/page_content_manager.py,sha256=jXWscZyiFNLGMiuJ8Da9P26q_9Hit9_G1j0rVDlOc5M,6224
36
+ notionary/page/content/page_content_manager.py,sha256=JM4ga-Y6k6mTbyH9YGYWbdrxpSLAdmZa845EwFyADMg,6142
37
37
  notionary/page/metadata/metadata_editor.py,sha256=61uiw8oB25O8ePhytoJvZDetuof5sjPoM6aoHZGo4wc,4949
38
38
  notionary/page/metadata/notion_icon_manager.py,sha256=ixZrWsHGVpmF05Ncy9LCt8vZlKAQHYFZW-2yI5JZZDI,1426
39
39
  notionary/page/metadata/notion_page_cover_manager.py,sha256=qgQxQE-bx4oWjLFUQvpXD5GzO1Mx7w7htz1xC2BOqUg,1717
@@ -49,8 +49,8 @@ notionary/page/relations/relation_operation_result.py,sha256=NDxBzGntOxc_89ti-HG
49
49
  notionary/util/logging_mixin.py,sha256=fKsx9t90bwvL74ZX3dU-sXdC4TZCQyO6qU9I8txkw_U,1369
50
50
  notionary/util/page_id_utils.py,sha256=EYNMxgf-7ghzL5K8lKZBZfW7g5CsdY0Xuj4IYmU8RPk,1381
51
51
  notionary/util/singleton_decorator.py,sha256=GTNMfIlVNRUVMw_c88xqd12-DcqZJjmyidN54yqiNVw,472
52
- notionary-0.1.16.dist-info/licenses/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
53
- notionary-0.1.16.dist-info/METADATA,sha256=tKeWZjbUCsadM9l0ocHVCfPwzdQxZQwhqgz9KLZJHQI,6154
54
- notionary-0.1.16.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
55
- notionary-0.1.16.dist-info/top_level.txt,sha256=fhONa6BMHQXqthx5PanWGbPL0b8rdFqhrJKVLf_adSs,10
56
- notionary-0.1.16.dist-info/RECORD,,
52
+ notionary-0.1.18.dist-info/licenses/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
53
+ notionary-0.1.18.dist-info/METADATA,sha256=-k4dWxkINEoOhfulMYuFZvP7WVsgejcVdAypcX0ldDM,8522
54
+ notionary-0.1.18.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
55
+ notionary-0.1.18.dist-info/top_level.txt,sha256=fhONa6BMHQXqthx5PanWGbPL0b8rdFqhrJKVLf_adSs,10
56
+ notionary-0.1.18.dist-info/RECORD,,