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.
- notionary/blocks/callout/callout_models.py +1 -0
- notionary/database/client.py +0 -2
- notionary/page/models.py +4 -9
- notionary/page/notion_page.py +27 -31
- notionary/page/writer/handler/equation_handler.py +1 -1
- notionary-0.2.26.dist-info/METADATA +270 -0
- {notionary-0.2.24.dist-info → notionary-0.2.26.dist-info}/RECORD +9 -9
- notionary-0.2.24.dist-info/METADATA +0 -250
- {notionary-0.2.24.dist-info → notionary-0.2.26.dist-info}/LICENSE +0 -0
- {notionary-0.2.24.dist-info → notionary-0.2.26.dist-info}/WHEEL +0 -0
notionary/database/client.py
CHANGED
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:
|
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:
|
288
|
+
parent: ParentObject
|
294
289
|
archived: bool
|
295
290
|
in_trash: bool
|
296
291
|
properties: dict[str, Any]
|
notionary/page/notion_page.py
CHANGED
@@ -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.
|
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
|
442
|
+
"Property '%s' not found in page properties", property_name
|
444
443
|
)
|
445
444
|
return None
|
446
445
|
|
447
|
-
|
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
|
-
|
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.
|
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.
|
481
|
-
self.logger.
|
482
|
-
"
|
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
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
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.
|
@@ -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
|
+
[](https://www.python.org/downloads/)
|
35
|
+
[](LICENSE)
|
36
|
+
[](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=
|
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=
|
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=
|
141
|
-
notionary/page/notion_page.py,sha256=
|
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=
|
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.
|
200
|
-
notionary-0.2.
|
201
|
-
notionary-0.2.
|
202
|
-
notionary-0.2.
|
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
|
-
[](https://www.python.org/downloads/)
|
35
|
-
[](LICENSE)
|
36
|
-
[](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
|
-
|
File without changes
|
File without changes
|