notionary 0.2.24__py3-none-any.whl → 0.2.26__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.
@@ -27,6 +27,7 @@ class CalloutBlock(BaseModel):
27
27
  icon: Optional[IconObject] = None
28
28
  children: Optional[list[Block]] = None
29
29
 
30
+
30
31
  class CreateCalloutBlock(BaseModel):
31
32
  type: Literal["callout"] = "callout"
32
33
  callout: CalloutBlock
@@ -1,7 +1,5 @@
1
1
  from typing import Any, Dict, Optional
2
2
 
3
- from urllib3.util import response
4
-
5
3
  from notionary.base_notion_client import BaseNotionClient
6
4
  from notionary.database.models import (
7
5
  NotionDatabaseResponse,
notionary/page/models.py CHANGED
@@ -2,6 +2,8 @@ from typing import Any, Literal, Optional, Union
2
2
 
3
3
  from pydantic import BaseModel, ConfigDict
4
4
 
5
+ from notionary.blocks.models import ParentObject
6
+
5
7
 
6
8
  class TextContent(BaseModel):
7
9
  content: str
@@ -241,13 +243,6 @@ class NotionCover(BaseModel):
241
243
  external: Optional[ExternalCover] = None
242
244
 
243
245
 
244
- # Parent types for Pydantic
245
- class NotionParent(BaseModel):
246
- type: str # 'database_id', 'page_id', 'workspace'
247
- database_id: Optional[str] = None
248
- page_id: Optional[str] = None
249
-
250
-
251
246
  # User type for Pydantic
252
247
  class NotionUser(BaseModel):
253
248
  object: str # 'user'
@@ -274,7 +269,7 @@ class NotionDatabaseResponse(BaseModel):
274
269
  properties: dict[
275
270
  str, Any
276
271
  ] # Using Any for flexibility with different property schemas
277
- parent: NotionParent
272
+ parent: ParentObject
278
273
  url: str
279
274
  public_url: Optional[str] = None
280
275
  archived: bool
@@ -290,7 +285,7 @@ class NotionPageResponse(BaseModel):
290
285
  last_edited_by: NotionUser
291
286
  cover: Optional[NotionCover] = None
292
287
  icon: Optional[Icon] = None
293
- parent: NotionParent
288
+ parent: ParentObject
294
289
  archived: bool
295
290
  in_trash: bool
296
291
  properties: dict[str, Any]
@@ -1,13 +1,16 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from ast import Dict
3
4
  import asyncio
4
5
  import random
5
6
  from typing import TYPE_CHECKING, Any, Callable, Optional, Union
6
7
 
8
+ from yaml import Token
9
+
7
10
  from notionary.blocks.client import NotionBlockClient
8
11
  from notionary.comments import CommentClient, Comment
9
12
  from notionary.blocks.syntax_prompt_builder import SyntaxPromptBuilder
10
- from notionary.blocks.models import DatabaseParent
13
+ from notionary.blocks.models import DatabaseParent, ParentObject
11
14
  from notionary.blocks.registry.block_registry import BlockRegistry
12
15
  from notionary.database.client import NotionDatabaseClient
13
16
  from notionary.file_upload.client import NotionFileUploadClient
@@ -61,6 +64,7 @@ class NotionPage(LoggingMixin):
61
64
 
62
65
  self._client = NotionPageClient(token=token)
63
66
  self._block_client = NotionBlockClient(token=token)
67
+ self._database_client = NotionDatabaseClient(token=token)
64
68
  self._comment_client = CommentClient(token=token)
65
69
  self._page_data = None
66
70
 
@@ -433,30 +437,20 @@ class NotionPage(LoggingMixin):
433
437
  """
434
438
  Get the value of a specific property.
435
439
  """
436
- if not self._parent_database:
437
- return None
438
-
439
- database_property_schema = self._parent_database.properties.get(property_name)
440
-
441
- if not database_property_schema:
440
+ if property_name not in self._properties:
442
441
  self.logger.warning(
443
- "Property '%s' not found in database schema", property_name
442
+ "Property '%s' not found in page properties", property_name
444
443
  )
445
444
  return None
446
445
 
447
- property_type = database_property_schema.get("type")
446
+ property_schema: dict = self._properties.get(property_name)
447
+
448
+ property_type = property_schema.get("type")
448
449
 
449
450
  if property_type == "relation":
450
451
  return await self._get_relation_property_values_by_name(property_name)
451
452
 
452
- if property_name not in self._properties:
453
- self.logger.warning(
454
- "Property '%s' not found in page properties", property_name
455
- )
456
- return None
457
-
458
- property_data = self._properties.get(property_name)
459
- return extract_property_value(property_data)
453
+ return extract_property_value(property_schema)
460
454
 
461
455
  async def _get_relation_property_values_by_name(
462
456
  self, property_name: str
@@ -464,7 +458,7 @@ class NotionPage(LoggingMixin):
464
458
  """
465
459
  Retrieve the titles of all related pages for a relation property.
466
460
  """
467
- page_property_schema = self.properties.get(property_name)
461
+ page_property_schema = self._properties.get(property_name)
468
462
  relation_page_ids = [
469
463
  rel.get("id") for rel in page_property_schema.get("relation", [])
470
464
  ]
@@ -477,23 +471,25 @@ class NotionPage(LoggingMixin):
477
471
  """
478
472
  Get the available options for a property (select, multi_select, status, relation).
479
473
  """
480
- if not self._parent_database:
481
- self.logger.error(
482
- "Parent database not set. Cannot get options for property: %s",
483
- property_name,
474
+ if property_name not in self.properties:
475
+ self.logger.warning(
476
+ "Property '%s' not found in page properties", property_name
484
477
  )
485
478
  return []
486
479
 
487
- try:
488
- return await self._parent_database.get_options_by_property_name(
489
- property_name=property_name
490
- )
491
- except Exception as e:
492
- self.logger.error(
493
- "Error getting options for property '%s': %s", property_name, str(e)
494
- )
495
- return []
480
+ property_schema: dict = self.properties.get(property_name)
481
+ property_type = property_schema.get("type")
482
+
483
+ if property_type in ["select", "multi_select", "status"]:
484
+ options = property_schema.get(property_type, {}).get("options", [])
485
+ return [option.get("name", "") for option in options]
486
+
487
+ if property_type == "relation" and self._parent_database:
488
+ return await self._parent_database._get_relation_options(property_name)
489
+
490
+ return []
496
491
 
492
+ # Fix this for pages that do not ah
497
493
  async def set_property_value_by_name(self, property_name: str, value: Any) -> Any:
498
494
  """
499
495
  Set the value of a specific property by its name.
@@ -8,7 +8,7 @@ from notionary.page.writer.handler.line_handler import (
8
8
 
9
9
 
10
10
  class EquationHandler(LineHandler):
11
- """Handles equation block specific logic with batching.
11
+ r"""Handles equation block specific logic with batching.
12
12
 
13
13
  Markdown syntax:
14
14
  $$
@@ -0,0 +1,270 @@
1
+ Metadata-Version: 2.3
2
+ Name: notionary
3
+ Version: 0.2.26
4
+ Summary: Python library for programmatic Notion workspace management - databases, pages, and content with advanced Markdown support
5
+ License: MIT
6
+ Author: Mathis Arends
7
+ Author-email: mathisarends27@gmail.com
8
+ Requires-Python: >=3.9
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Dist: aiofiles (>=24.1.0,<25.0.0)
17
+ Requires-Dist: httpx (>=0.28.0)
18
+ Requires-Dist: posthog (>=6.3.1,<7.0.0)
19
+ Requires-Dist: pydantic (>=2.11.4)
20
+ Requires-Dist: python-dotenv (>=1.1.0)
21
+ Project-URL: Homepage, https://github.com/mathisarends/notionary
22
+ Description-Content-Type: text/markdown
23
+
24
+ <picture>
25
+ <source media="(prefers-color-scheme: dark)" srcset="./static/notionary-dark.png">
26
+ <source media="(prefers-color-scheme: light)" srcset="./static/notionary-light.png">
27
+ <img alt="Notionary logo: dark mode shows a white logo, light mode shows a black logo." src="./static/browser-use.png" width="full">
28
+ </picture>
29
+
30
+ <h1 align="center">The Modern Notion API for Python & AI Agents</h1>
31
+
32
+ <div align="center">
33
+
34
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
35
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
36
+ [![Documentation](https://img.shields.io/badge/docs-mathisarends.github.io-blue.svg)](https://mathisarends.github.io/notionary/)
37
+
38
+ **Transform complex Notion API interactions into simple, Pythonic code.**
39
+ Perfect for developers building AI agents, automation workflows, and dynamic content systems.
40
+
41
+ </div>
42
+
43
+ ---
44
+
45
+ ## Why Notionary?
46
+
47
+ - **AI-Native Design** - Built specifically for AI agents with schema-driven markdown syntax
48
+ - **Smart Discovery** - Find pages and databases by name with fuzzy matching—no more hunting for IDs
49
+ - **Extended Markdown** - Rich syntax for toggles, columns, callouts, and media uploads
50
+ - **Async-First** - Modern Python with full async/await support and high performance
51
+ - **Round-Trip** - Read existing content, modify it, and write it back while preserving formatting
52
+ - **Complete Coverage** - Every Notion block type supported with type safety
53
+
54
+ ---
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ pip install notionary
60
+ ```
61
+
62
+ Set up your [Notion integration](https://www.notion.so/profile/integrations) and configure your token:
63
+
64
+ ```bash
65
+ export NOTION_SECRET=your_integration_key
66
+ ```
67
+
68
+ ---
69
+
70
+ ## See It in Action
71
+
72
+ ### Creating Rich Database Entries
73
+
74
+ https://github.com/user-attachments/assets/da8b4691-bee4-4b0f-801e-dccacb630398
75
+
76
+ *Create styled project pages with properties, content, and rich formatting*
77
+
78
+ ### Local File Uploads (Videos & Images)
79
+
80
+ https://github.com/user-attachments/assets/a079ec01-bb56-4c65-8260-7b1fca42ac68
81
+
82
+ *Upload videos and images using simple markdown syntax - files are automatically uploaded to Notion*
83
+
84
+ ---
85
+
86
+ ## Quick Start
87
+
88
+ ### Find → Create → Update Flow
89
+
90
+ ```python
91
+ import asyncio
92
+ from notionary import NotionPage, NotionDatabase
93
+
94
+ async def main():
95
+ # Find pages by name - fuzzy matching included!
96
+ page = await NotionPage.from_page_name("Meeting Notes")
97
+
98
+ # Option 1: Direct Extended Markdown
99
+ await page.append_markdown("""
100
+ ## Action Items
101
+ - [x] Review project proposal
102
+ - [ ] Schedule team meeting
103
+ - [ ] Update documentation
104
+
105
+ [callout](Meeting decisions require follow-up "💡")
106
+
107
+ +++ Details
108
+ Additional context and next steps...
109
+ +++
110
+ """)
111
+
112
+ # Option 2: Type-Safe Builder (maps to same markdown internally)
113
+ await page.append_markdown(lambda builder: (
114
+ builder
115
+ .h2("Project Status")
116
+ .callout("Milestone reached!", "🎉")
117
+ .columns(
118
+ lambda col: col.h3("Completed").bulleted_list([
119
+ "API design", "Database setup", "Authentication"
120
+ ]),
121
+ lambda col: col.h3("In Progress").bulleted_list([
122
+ "Frontend UI", "Testing", "Documentation"
123
+ ]),
124
+ width_ratios=[0.6, 0.4]
125
+ )
126
+ .toggle("Budget Details", lambda t: t
127
+ .table(["Item", "Cost", "Status"], [
128
+ ["Development", "$15,000", "Paid"],
129
+ ["Design", "$8,000", "Pending"]
130
+ ])
131
+ )
132
+ ))
133
+
134
+ asyncio.run(main())
135
+ ```
136
+
137
+ ### Complete Block Support
138
+
139
+ Every Notion block type with extended syntax:
140
+
141
+ | Block Type | Markdown Syntax | Use Case |
142
+ |------------|-----------------|----------|
143
+ | **Callouts** | `[callout](Text "🔥")` | Highlighting key information |
144
+ | **Toggles** | `+++ Title\nContent\n+++` | Collapsible sections |
145
+ | **Columns** | `::: columns\n::: column\nContent\n:::\n:::` | Side-by-side layouts |
146
+ | **Tables** | Standard markdown tables | Structured data |
147
+ | **Media** | `[video](./file.mp4)(caption:Description)` | Auto-uploading files |
148
+ | **Code** | Standard code fences with captions | Code snippets |
149
+ | **Equations** | `$LaTeX$` | Mathematical expressions |
150
+ | **TOC** | `[toc](blue_background)` | Auto-generated navigation |
151
+
152
+ ---
153
+
154
+ ## What You Can Build 💡
155
+
156
+ ### **AI Content Systems**
157
+ - **Report Generation**: AI agents that create structured reports, documentation, and analysis
158
+ - **Content Pipelines**: Automated workflows that process data and generate Notion pages
159
+ - **Knowledge Management**: AI-powered documentation systems with smart categorization
160
+
161
+ ### **Workflow Automation**
162
+ - **Project Management**: Sync project status, update timelines, generate progress reports
163
+ - **Data Integration**: Connect external APIs and databases to Notion workspaces
164
+ - **Template Systems**: Dynamic page generation from templates and data sources
165
+
166
+ ### **Content Management**
167
+ - **Bulk Operations**: Mass page updates, content migration, and database management
168
+ - **Media Handling**: Automated image/video uploads with proper organization
169
+ - **Cross-Platform**: Sync content between Notion and other platforms
170
+
171
+ ---
172
+
173
+ ## Key Features
174
+
175
+ <table>
176
+ <tr>
177
+ <td width="50%">
178
+
179
+ ### Smart Discovery
180
+ - Find pages/databases by name
181
+ - Fuzzy matching for approximate searches
182
+ - No more hunting for IDs or URLs
183
+
184
+ ### Extended Markdown
185
+ - Rich syntax beyond standard markdown
186
+ - Callouts, toggles, columns, media uploads
187
+ - Schema provided for AI agent integration
188
+
189
+ ### Modern Python
190
+ - Full async/await support
191
+ - Type hints throughout
192
+ - High-performance batch operations
193
+
194
+ </td>
195
+ <td width="50%">
196
+
197
+ ### Round-Trip Editing
198
+ - Read existing content as markdown
199
+ - Edit and modify preserving formatting
200
+ - Write back to Notion seamlessly
201
+
202
+ ### AI-Ready Architecture
203
+ - Schema-driven syntax for LLM prompts
204
+ - Perfect for AI content generation
205
+ - Handles complex nested structures
206
+
207
+ ### Complete Coverage
208
+ - Every Notion block type supported
209
+ - File uploads with automatic handling
210
+ - Database operations and properties
211
+
212
+ </td>
213
+ </tr>
214
+ </table>
215
+
216
+ ---
217
+
218
+ ## Examples & Documentation
219
+
220
+ ### Full Documentation
221
+ [**mathisarends.github.io/notionary**](https://mathisarends.github.io/notionary/) - Complete API reference, guides, and tutorials
222
+
223
+ ### Quick Links
224
+ - [**Getting Started**](https://mathisarends.github.io/notionary/get-started/) - Setup and first steps
225
+ - [**Page Management**](https://mathisarends.github.io/notionary/page/) - Content and properties
226
+ - [**Database Operations**](https://mathisarends.github.io/notionary/database/) - Queries and management
227
+ - [**Block Types Reference**](https://mathisarends.github.io/notionary/blocks/) - Complete syntax guide
228
+
229
+ ### Hands-On Examples
230
+
231
+ **Core Functionality:**
232
+ - [Page Management](examples/page_example.py) - Create, update, and manage pages
233
+ - [Database Operations](examples/database.py) - Connect and query databases
234
+ - [Workspace Discovery](examples/workspace_discovery.py) - Explore your workspace
235
+
236
+ **Extended Markdown:**
237
+ - [Basic Formatting](examples/markdown/basic.py) - Text, lists, and links
238
+ - [Callouts & Highlights](examples/markdown/callout.py) - Information boxes
239
+ - [Toggle Sections](examples/markdown/toggle.py) - Collapsible content
240
+ - [Multi-Column Layouts](examples/markdown/columns.py) - Side-by-side design
241
+ - [Tables & Data](examples/markdown/table.py) - Structured presentations
242
+
243
+ ---
244
+
245
+ ## Contributing
246
+
247
+ We welcome contributions from the community! Whether you're:
248
+ - **Fixing bugs** - Help improve stability and reliability
249
+ - **Adding features** - Extend functionality for new use cases
250
+ - **Improving docs** - Make the library more accessible
251
+ - **Sharing examples** - Show creative applications and patterns
252
+
253
+ Check our [**Contributing Guide**](https://mathisarends.github.io/notionary/contributing/) to get started.
254
+
255
+ ---
256
+
257
+ <div align="center">
258
+
259
+ **Ready to revolutionize your Notion workflows?**
260
+
261
+ [📖 **Read the Docs**](https://mathisarends.github.io/notionary/) • [🚀 **Getting Started**](https://mathisarends.github.io/notionary/get-started/) • [💻 **Browse Examples**](examples/)
262
+
263
+ *Built with ❤️ for Python developers and AI agents*
264
+
265
+ ---
266
+
267
+ **Transform complex Notion API interactions into simple, powerful code.**
268
+
269
+ </div>
270
+
@@ -22,7 +22,7 @@ notionary/blocks/bulleted_list/bulleted_list_models.py,sha256=QN21PIwAP7MQoIjZeU
22
22
  notionary/blocks/callout/__init__.py,sha256=17rdvOF5W1aPxkp-pk13rLgkx6pIciCsub3ncAv_zXk,363
23
23
  notionary/blocks/callout/callout_element.py,sha256=6Ss1jv1cqAM4GuNGvuy7dCFjpp-dLavf-wXevn3IEmw,3575
24
24
  notionary/blocks/callout/callout_markdown_node.py,sha256=2zZNMwg8uiGBqaMOUVOTlIK8kiq20IQ0Ylv7ZFUm-bc,602
25
- notionary/blocks/callout/callout_models.py,sha256=E58ko2ujDV80HlI20S9etbCMTm6a_IaSp9waUozWTa8,863
25
+ notionary/blocks/callout/callout_models.py,sha256=g_xU7oiRRseoSO86dqHPIiwoseGvvnl3jsPZbBMT-mE,865
26
26
  notionary/blocks/child_database/__init__.py,sha256=FzjjHOS9Je2oXuxLK9S9Oq56-EDEZRTJBfDzkacFpY0,368
27
27
  notionary/blocks/child_database/child_database_element.py,sha256=1pxtoB_XTIWorYp984TpsPMZy8A5IdQ15nJALyzme-c,2279
28
28
  notionary/blocks/child_database/child_database_models.py,sha256=SP6S9tKTetKNdCkYY3QCxeXd2lq1DyfdNvDhKlhD22Q,264
@@ -123,7 +123,7 @@ notionary/comments/__init__.py,sha256=G0OWsaN2VgbykvhLlNSweL_f0bl16j9NpidH2UNbFc
123
123
  notionary/comments/client.py,sha256=vWjgPFk_TPY7peq10aJc7WTG-b0q6Fn8qirAlzlqLls,7311
124
124
  notionary/comments/models.py,sha256=O2-yg-0Xrs8xrzLUa4793FlyNn3HbTRsv4dqaskI6ps,3409
125
125
  notionary/database/__init__.py,sha256=4tdML0fBzkOCpiWT6q-L--5NELFLbTPD0IUA_E8yZno,155
126
- notionary/database/client.py,sha256=mN_8XHvIQkRxiWbgBfvncgw4IRiCFX3bVLMLBvtk1Ig,5398
126
+ notionary/database/client.py,sha256=NQWUcfMLAYsnTefFgOjgOHMYN7rn_IRBrsKPUlUY0c8,5361
127
127
  notionary/database/database.py,sha256=sdo830KVInR4enaEaeMHaPadNfYnPLy5R3OW2f74w28,16558
128
128
  notionary/database/database_filter_builder.py,sha256=YIkdghD5VbdwLJISMRiJ0WIJTm8jcDIL22yrvZau4sA,5950
129
129
  notionary/database/database_provider.py,sha256=HB-hZ9pMjronLJS8w_b1GiQ-Ecz1uJbrWpnePL67BCA,8956
@@ -137,8 +137,8 @@ notionary/file_upload/models.py,sha256=bSNgw5WzkOuotyalqkkcVC_Ue6YRHR-CSJV7nZRV_
137
137
  notionary/file_upload/notion_file_upload.py,sha256=vOEEh8g8Sj4JedrK9e-NYjJ0HXH3iGdM5N74kkVXVZQ,13221
138
138
  notionary/page/client.py,sha256=IOsjWOsmODxOq-7OF0y-gcuC2HUbMIT0SvJZHrH9weQ,4520
139
139
  notionary/page/markdown_whitespace_processor.py,sha256=SbWLL6bdeTGds_khDNX2mQe00lGYUFvH6PX8_xpNvBA,4634
140
- notionary/page/models.py,sha256=pD8FlK8KtnUrIITTd2jg_yJICakgPE4ysZiS9KiMpr0,7088
141
- notionary/page/notion_page.py,sha256=6aQqAqiEg6gb5lISKkV6a2UzIixgOZ-7eivlvXpyHvc,23689
140
+ notionary/page/models.py,sha256=zk9QOgCDzVfYfT1Gp2bL1_Bw-QUyfWxwTTIPzIayQ7g,6945
141
+ notionary/page/notion_page.py,sha256=P8J2lvq7xM0UwbL0wEFGi9w7jNPg43ewutmYpJINe1w,23662
142
142
  notionary/page/page_content_deleting_service.py,sha256=G3im6VotG1tgI-SaqoQR-gSnOloF6CEnft1qxLps4as,4546
143
143
  notionary/page/page_content_writer.py,sha256=t8N7yfW--ac7szvDmTdecFEfcF5Nz95vyCQ-lpYcOUw,3046
144
144
  notionary/page/page_context.py,sha256=27vrTRZP7NsaS4dEp4pBNR30Re2hh00qKlL3xt4YtpI,1773
@@ -161,7 +161,7 @@ notionary/page/writer/handler/__init__.py,sha256=8rAzBvmeaPYoYIB5Fd3XHCKFMmbSdlD
161
161
  notionary/page/writer/handler/code_handler.py,sha256=Xn5SitI2fnJkS38_RGtMEY0EOqwy8m-wnqaNetRx7hY,2671
162
162
  notionary/page/writer/handler/column_handler.py,sha256=JIwvWMPiNsMKAG6UEMpkiglD0kKsXQFu1dP1V6L5Keg,5415
163
163
  notionary/page/writer/handler/column_list_handler.py,sha256=k_exJ87d8i9MGV_uKxAB_mdpmcf5nfOZQ1bqHUoJHiA,5309
164
- notionary/page/writer/handler/equation_handler.py,sha256=vflcoaSNNnLxbI_8oE_o33etmF3CxvWYnVQCJ7gbbd8,2844
164
+ notionary/page/writer/handler/equation_handler.py,sha256=ipS26TfAAOAUmOLPl36oMDurRHxXBfFMFZCrJe2iYUE,2845
165
165
  notionary/page/writer/handler/line_handler.py,sha256=miuU7MXJj1Ae_B_r4a84s9tJaJ8xWNo-LAeD6RqJ-aM,1163
166
166
  notionary/page/writer/handler/line_processing_context.py,sha256=F2GxDXIOgvZHxiDP-VDe8JUHGcsszMexPG0W9E9y39E,1739
167
167
  notionary/page/writer/handler/regular_line_handler.py,sha256=2T8xOi4ybcugMJL-sPyVvU0KRVQzFSPpvLibrixIJLA,3223
@@ -196,7 +196,7 @@ notionary/util/page_id_utils.py,sha256=AA00kRO-g3Cc50tf_XW_tb5RBuPKLuBxRa0D8LYhL
196
196
  notionary/util/singleton.py,sha256=CKAvykndwPRZsA3n3MAY_XdCR59MBjjKP0vtm2BcvF0,428
197
197
  notionary/util/singleton_metaclass.py,sha256=DMvrh0IbAV8nIG1oX-2Yz57Uk1YHB647DNxoI3pAT3s,809
198
198
  notionary/workspace.py,sha256=QP4WcOIdQnlVr4M7hpGaFT-Fori_QRhsV-SBC2lnwTU,3809
199
- notionary-0.2.24.dist-info/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
200
- notionary-0.2.24.dist-info/METADATA,sha256=TAnB9piH5MJLjSJSgv3opZrGb7vVtqT8HFKrJr44ohM,9580
201
- notionary-0.2.24.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
202
- notionary-0.2.24.dist-info/RECORD,,
199
+ notionary-0.2.26.dist-info/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
200
+ notionary-0.2.26.dist-info/METADATA,sha256=YQ47PvnCFcARf1p99-fZWoYnedbR0S5G2rQRUa6e4KY,9143
201
+ notionary-0.2.26.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
202
+ notionary-0.2.26.dist-info/RECORD,,
@@ -1,250 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: notionary
3
- Version: 0.2.24
4
- Summary: Python library for programmatic Notion workspace management - databases, pages, and content with advanced Markdown support
5
- License: MIT
6
- Author: Mathis Arends
7
- Author-email: mathisarends27@gmail.com
8
- Requires-Python: >=3.9
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.9
12
- Classifier: Programming Language :: Python :: 3.10
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Classifier: Programming Language :: Python :: 3.13
16
- Requires-Dist: aiofiles (>=24.1.0,<25.0.0)
17
- Requires-Dist: httpx (>=0.28.0)
18
- Requires-Dist: posthog (>=6.3.1,<7.0.0)
19
- Requires-Dist: pydantic (>=2.11.4)
20
- Requires-Dist: python-dotenv (>=1.1.0)
21
- Project-URL: Homepage, https://github.com/mathisarends/notionary
22
- Description-Content-Type: text/markdown
23
-
24
- <picture>
25
- <source media="(prefers-color-scheme: dark)" srcset="./static/notionary-dark.png">
26
- <source media="(prefers-color-scheme: light)" srcset="./static/notionary-light.png">
27
- <img alt="Notionary logo: dark mode shows a white logo, light mode shows a black logo." src="./static/browser-use.png" width="full">
28
- </picture>
29
-
30
- <h1 align="center">Notion API simplified for Python developers 🐍</h1>
31
-
32
- <div align="center">
33
-
34
- [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
35
- [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
36
- [![Documentation](https://img.shields.io/badge/docs-mathisarends.github.io-blue.svg)](https://mathisarends.github.io/notionary/)
37
-
38
- Transform complex Notion API interactions into simple, Pythonic code. Build AI agents, automate workflows, and create dynamic content with ease.
39
-
40
- </div>
41
-
42
- ---
43
-
44
- ## Why Notionary?
45
-
46
- - **Smart Discovery**: Find pages and databases by name—no more hunting for URLs or IDs
47
- - **Rich Markdown**: Convert extended Markdown (callouts, toggles, columns) directly into beautiful Notion blocks
48
- - **Async-First**: Built for modern Python with full async/await support and high performance
49
- - **AI-Ready**: Perfect foundation for AI agents that generate and manage Notion content
50
- - **Round-Trip**: Read existing content, modify it, and write it back while preserving formatting
51
-
52
- ---
53
-
54
- ## Quick Start
55
-
56
- ```bash
57
- pip install notionary
58
- ```
59
-
60
- Set up your [Notion integration](https://www.notion.so/profile/integrations) and add your token:
61
-
62
- ```bash
63
- NOTION_SECRET=your_integration_key
64
- ```
65
-
66
- ### Simple Flow: Find → Create → Update
67
-
68
- <video width="100%" controls>
69
- <source src="./static/demo.mp4" type="video/mp4">
70
- Your browser does not support the video tag.
71
- </video>
72
-
73
- _Demo: Converting markdown to structured Notion content with callouts, columns, and tables_
74
-
75
- ```python
76
- import asyncio
77
- from notionary import NotionPage, NotionDatabase
78
-
79
- async def main():
80
- # Work with pages - find by name, no exact match needed!
81
- page = await NotionPage.from_page_name("Meeting Notes")
82
-
83
- # Direct Markdown - quick & intuitive
84
- await page.append_markdown("""
85
- ## Action Items
86
- - Review project proposal
87
- - Schedule team meeting
88
- - Update documentation
89
-
90
- [callout](Important meeting decisions require follow-up "💡")
91
- """)
92
-
93
- # Builder Pattern - type-safe & powerful for complex layouts
94
- await page.append_markdown(lambda builder: (
95
- builder
96
- .h2("Project Status")
97
- .callout("Project milestone reached!", "🎉")
98
- .columns(
99
- lambda col: (col
100
- .h3("Completed")
101
- .bulleted_list(["API design", "Database setup", "Authentication"])
102
- ),
103
- lambda col: (col
104
- .h3("In Progress")
105
- .bulleted_list(["Frontend UI", "Testing", "Documentation"])
106
- )
107
- )
108
- .table(
109
- headers=["Task", "Owner", "Due Date"],
110
- rows=[
111
- ["Launch prep", "Alice", "2024-03-15"],
112
- ["Marketing", "Bob", "2024-03-20"]
113
- ]
114
- )
115
- ))
116
-
117
- asyncio.run(main())
118
- ```
119
-
120
- ### Create Rich Database Entries
121
-
122
- <video width="100%" controls>
123
- <source src="./static/create_page_in_database_demo.mp4" type="video/mp4">
124
- Your browser does not support the video tag.
125
- </video>
126
-
127
- _Demo: Creating a styled project page in a Notion database with properties, content, and rich formatting_
128
-
129
- ```python
130
- # Work with databases - connect and create styled entries
131
- db = await NotionDatabase.from_database_name("Projects")
132
-
133
- # Create new project with full styling
134
- project = await db.create_blank_page()
135
- await project.set_title("New Marketing Campaign")
136
- await project.set_emoji_icon("🚀")
137
- await project.set_random_gradient_cover()
138
-
139
- # Set database properties
140
- await project.set_property_value_by_name("Status", "Planning")
141
- await project.set_property_value_by_name("Priority", "High")
142
- await project.set_property_value_by_name("Team Lead", "sarah@company.com")
143
-
144
- # Add rich content to the new page
145
- await project.replace_content(lambda builder: (
146
- builder
147
- .h1("Campaign Overview")
148
- .callout("New marketing initiative targeting Q2 growth", "🎯")
149
- .h2("Goals & Objectives")
150
- .numbered_list([
151
- "Increase brand awareness by 25%",
152
- "Generate 500 qualified leads",
153
- "Launch in 3 target markets"
154
- ])
155
- .h2("Budget Breakdown")
156
- .table(
157
- headers=["Category", "Allocated", "Spent", "Remaining"],
158
- rows=[
159
- ["Digital Ads", "$15,000", "$3,200", "$11,800"],
160
- ["Content Creation", "$8,000", "$1,500", "$6,500"],
161
- ["Events", "$12,000", "$0", "$12,000"]
162
- ]
163
- )
164
- .divider()
165
- .toggle("Technical Requirements", lambda toggle: (
166
- toggle
167
- .paragraph("Platform specifications and integration details.")
168
- .bulleted_list([
169
- "CRM integration with Salesforce",
170
- "Analytics tracking setup",
171
- "Landing page development"
172
- ])
173
- ))
174
- ))
175
-
176
- print(f"✅ Created styled project: {project.url}")
177
- ```
178
-
179
- ### Extended Markdown Syntax
180
-
181
- Notionary supports rich formatting with callouts, toggles, multi-column layouts, tables, media embeds, and more. Use either direct markdown syntax or the type-safe builder pattern.
182
-
183
- See the complete [Block Types documentation](https://mathisarends.github.io/notionary/blocks/) for all available formatting options and syntax examples.
184
-
185
- ## What You Can Build
186
-
187
- - **AI Content Generation** - Perfect for AI agents that create structured reports and documentation
188
- - **Workflow Automation** - Update project status, sync data between databases, generate reports
189
- - **Dynamic Documentation** - Auto-generate team docs, API references, and knowledge bases
190
- - **Content Management** - Bulk page updates, template generation, and content migration
191
-
192
- ## Core Features
193
-
194
- | Feature | Description |
195
- | -------------------- | ------------------------------------------------------ |
196
- | **Smart Discovery** | Find pages/databases by name with fuzzy matching |
197
- | **Rich Markdown** | Extended syntax for callouts, toggles, columns, tables |
198
- | **Async-First** | Modern Python with full async/await support |
199
- | **Round-Trip** | Read content as markdown, edit, and write back |
200
- | **AI-Ready** | Generate system prompts for AI content creation |
201
- | **All Block Types** | Support for every Notion block type |
202
- | **Type Safety** | Full type hints for better IDE support |
203
- | **High Performance** | Efficient batch operations and caching |
204
-
205
- ## Examples & Documentation
206
-
207
- Explore comprehensive guides and real-world examples:
208
-
209
- - **[📖 Full Documentation](https://mathisarends.github.io/notionary/)** - Complete API reference and guides
210
- - **[Getting Started](https://mathisarends.github.io/notionary/get-started/)** - Quick setup and first steps
211
- - **[Page Management](https://mathisarends.github.io/notionary/page/)** - Work with page content and properties
212
- - **[Database Operations](https://mathisarends.github.io/notionary/database/)** - Query and manage databases
213
- - **[Block Types](https://mathisarends.github.io/notionary/blocks/)** - Complete formatting reference
214
-
215
- Check out the `examples/` directory for hands-on tutorials:
216
-
217
- ### Core Examples
218
-
219
- - **[Page Management](examples/page_example.py)** - Create, update, and manage pages
220
- - **[Database Operations](examples/database.py)** - Connect to and query databases
221
- - **[Workspace Discovery](examples/workspace_discovery.py)** - Explore your workspace
222
-
223
- ### Markdown Examples
224
-
225
- - **[Basic Formatting](examples/markdown/basic.py)** - Text, lists, and links
226
- - **[Callouts](examples/markdown/callout.py)** - Eye-catching information boxes
227
- - **[Toggles](examples/markdown/toggle.py)** - Collapsible content sections
228
- - **[Multi-Column](examples/markdown/columns.py)** - Side-by-side layouts
229
- - **[Tables](examples/markdown/table.py)** - Structured data presentation
230
-
231
- ## Contributing
232
-
233
- We'd love your help making Notionary even better!
234
-
235
- Whether it's fixing bugs, adding features, improving docs, or sharing examples - all contributions are welcome.
236
-
237
- See our [Contributing Guide](https://mathisarends.github.io/notionary/contributing/) to get started.
238
-
239
- ---
240
-
241
- <div align="center">
242
-
243
- **Ready to transform your Notion workflow?**
244
-
245
- [📖 Read the Docs](https://mathisarends.github.io/notionary/) • [Getting Started](https://mathisarends.github.io/notionary/get-started/) • [Examples](examples/)
246
-
247
- Built with ❤️ for the Python community
248
-
249
- </div>
250
-