better-notion 1.4.0__py3-none-any.whl → 1.5.1__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.
- better_notion/_api/collections/databases.py +32 -0
- better_notion/_cli/commands/databases.py +147 -24
- better_notion/_cli/commands/pages.py +270 -293
- better_notion/_sdk/models/database.py +12 -7
- better_notion/plugins/official/agents.py +22 -2
- better_notion/plugins/official/agents_cli.py +29 -4
- better_notion/plugins/official/agents_sdk/managers.py +29 -1
- better_notion/utils/agents/schemas.py +91 -68
- better_notion/utils/agents/workspace.py +43 -29
- better_notion/utils/validators.py +132 -0
- {better_notion-1.4.0.dist-info → better_notion-1.5.1.dist-info}/METADATA +1 -1
- {better_notion-1.4.0.dist-info → better_notion-1.5.1.dist-info}/RECORD +15 -14
- {better_notion-1.4.0.dist-info → better_notion-1.5.1.dist-info}/WHEEL +0 -0
- {better_notion-1.4.0.dist-info → better_notion-1.5.1.dist-info}/entry_points.txt +0 -0
- {better_notion-1.4.0.dist-info → better_notion-1.5.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -73,3 +73,35 @@ class DatabaseCollection:
|
|
|
73
73
|
# Ensure parent is set to the database
|
|
74
74
|
page_data = {"parent": {"database_id": database_id}, **kwargs}
|
|
75
75
|
return await self._api._request("POST", "/pages", json=page_data)
|
|
76
|
+
|
|
77
|
+
async def create(
|
|
78
|
+
self,
|
|
79
|
+
parent: dict[str, Any],
|
|
80
|
+
title: str,
|
|
81
|
+
properties: dict[str, Any]
|
|
82
|
+
) -> dict[str, Any]:
|
|
83
|
+
"""Create a new database.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
parent: Parent object (e.g., {"type": "page_id", "page_id": "..."})
|
|
87
|
+
title: Database title
|
|
88
|
+
properties: Database schema/properties configuration
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Raw database data dict from Notion API.
|
|
92
|
+
|
|
93
|
+
Raises:
|
|
94
|
+
ValidationError: If the database configuration is invalid.
|
|
95
|
+
NotFoundError: If the parent page does not exist.
|
|
96
|
+
"""
|
|
97
|
+
# Build title array
|
|
98
|
+
title_array = [{"type": "text", "text": {"content": title}}]
|
|
99
|
+
|
|
100
|
+
# Create database request
|
|
101
|
+
database_data = {
|
|
102
|
+
"parent": parent,
|
|
103
|
+
"title": title_array,
|
|
104
|
+
"properties": properties
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return await self._api._request("POST", "/databases", json=database_data)
|
|
@@ -5,7 +5,6 @@ This module provides commands for managing Notion databases.
|
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
import asyncio
|
|
9
8
|
import json
|
|
10
9
|
from typing import Any
|
|
11
10
|
|
|
@@ -19,6 +18,49 @@ from better_notion._sdk.client import NotionClient
|
|
|
19
18
|
app = AsyncTyper(help="Databases commands")
|
|
20
19
|
|
|
21
20
|
|
|
21
|
+
# Schema templates for common use cases
|
|
22
|
+
SCHEMA_TEMPLATES = {
|
|
23
|
+
"minimal": {
|
|
24
|
+
"description": "Database with only a title property (minimal schema)",
|
|
25
|
+
"schema": {}
|
|
26
|
+
},
|
|
27
|
+
"simple": {
|
|
28
|
+
"description": "Simple database with title, text, and number properties",
|
|
29
|
+
"schema": {
|
|
30
|
+
"Notes": {"type": "rich_text"},
|
|
31
|
+
"Count": {"type": "number"}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"task": {
|
|
35
|
+
"description": "Task tracking database with status, priority, and due date",
|
|
36
|
+
"schema": {
|
|
37
|
+
"Status": {
|
|
38
|
+
"type": "select",
|
|
39
|
+
"select": {
|
|
40
|
+
"options": [
|
|
41
|
+
{"name": "Not Started", "color": "gray"},
|
|
42
|
+
{"name": "In Progress", "color": "blue"},
|
|
43
|
+
{"name": "Completed", "color": "green"}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"Priority": {
|
|
48
|
+
"type": "select",
|
|
49
|
+
"select": {
|
|
50
|
+
"options": [
|
|
51
|
+
{"name": "Low", "color": "gray"},
|
|
52
|
+
{"name": "Medium", "color": "yellow"},
|
|
53
|
+
{"name": "High", "color": "orange"},
|
|
54
|
+
{"name": "Critical", "color": "red"}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"Due Date": {"type": "date"}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
22
64
|
def get_client() -> NotionClient:
|
|
23
65
|
"""Get authenticated Notion client."""
|
|
24
66
|
config = Config.load()
|
|
@@ -48,34 +90,115 @@ def get(database_id: str) -> None:
|
|
|
48
90
|
|
|
49
91
|
|
|
50
92
|
@app.command()
|
|
51
|
-
def create(
|
|
93
|
+
async def create(
|
|
52
94
|
parent: str = typer.Option(..., "--parent", "-p", help="Parent page ID"),
|
|
53
95
|
title: str = typer.Option(..., "--title", "-t", help="Database title"),
|
|
54
96
|
schema: str = typer.Option("{}", "--schema", "-s", help="JSON schema for properties"),
|
|
97
|
+
template: str = typer.Option(None, "--template", help="Use a predefined schema template (minimal, simple, task)"),
|
|
55
98
|
) -> None:
|
|
56
|
-
"""Create a new database.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
99
|
+
"""Create a new database.
|
|
100
|
+
|
|
101
|
+
Schema Format:
|
|
102
|
+
The schema should be a JSON object mapping property names to their types.
|
|
103
|
+
Each property should have a "type" field and type-specific configuration.
|
|
104
|
+
|
|
105
|
+
Common property types:
|
|
106
|
+
- title: {"type": "title"} (Note: Every database must have exactly one title property)
|
|
107
|
+
- rich_text: {"type": "rich_text"}
|
|
108
|
+
- number: {"type": "number", "number": {"format": "number"}}
|
|
109
|
+
- select: {"type": "select", "select": {"options": [{"name": "Option1", "color": "gray"}]}}
|
|
110
|
+
- date: {"type": "date"}
|
|
111
|
+
- checkbox: {"type": "checkbox"}
|
|
112
|
+
- email: {"type": "email"}
|
|
113
|
+
- url: {"type": "url"}
|
|
114
|
+
- phone: {"type": "phone_number"}
|
|
115
|
+
|
|
116
|
+
Examples:
|
|
117
|
+
# Minimal database (title only)
|
|
118
|
+
notion databases create --parent page123 --title "My Database" --template minimal
|
|
119
|
+
|
|
120
|
+
# Simple custom schema
|
|
121
|
+
notion databases create --parent page123 --title "Tasks" \\
|
|
122
|
+
--schema '{"Status": {"type": "select", "select": {"options": [{"name": "Todo", "color": "gray"}]}}}'
|
|
123
|
+
|
|
124
|
+
# Use a predefined template
|
|
125
|
+
notion databases create --parent page123 --title "Task Tracker" --template task
|
|
126
|
+
|
|
127
|
+
# Show available templates
|
|
128
|
+
notion database-templates
|
|
129
|
+
"""
|
|
130
|
+
try:
|
|
131
|
+
client = get_client()
|
|
132
|
+
parent_page = await client.pages.get(parent)
|
|
133
|
+
|
|
134
|
+
# Use template if specified
|
|
135
|
+
if template:
|
|
136
|
+
if template not in SCHEMA_TEMPLATES:
|
|
137
|
+
result = format_error(
|
|
138
|
+
"INVALID_TEMPLATE",
|
|
139
|
+
f"Template '{template}' not found. Available templates: {', '.join(SCHEMA_TEMPLATES.keys())}. Use 'notion database-templates' to see all templates.",
|
|
140
|
+
retry=False
|
|
141
|
+
)
|
|
142
|
+
typer.echo(result)
|
|
143
|
+
raise typer.Exit(code=1)
|
|
144
|
+
schema_dict = SCHEMA_TEMPLATES[template]["schema"]
|
|
145
|
+
else:
|
|
146
|
+
# Parse custom schema
|
|
147
|
+
try:
|
|
148
|
+
schema_dict = json.loads(schema)
|
|
149
|
+
except json.JSONDecodeError as e:
|
|
150
|
+
result = format_error(
|
|
151
|
+
"INVALID_SCHEMA",
|
|
152
|
+
f"Invalid JSON schema: {str(e)}",
|
|
153
|
+
retry=False
|
|
154
|
+
)
|
|
155
|
+
typer.echo(result)
|
|
156
|
+
raise typer.Exit(code=1)
|
|
157
|
+
|
|
158
|
+
# Validate schema structure
|
|
159
|
+
if not isinstance(schema_dict, dict):
|
|
160
|
+
result = format_error(
|
|
161
|
+
"INVALID_SCHEMA",
|
|
162
|
+
"Schema must be a JSON object (dictionary)",
|
|
163
|
+
retry=False
|
|
67
164
|
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
165
|
+
typer.echo(result)
|
|
166
|
+
raise typer.Exit(code=1)
|
|
167
|
+
|
|
168
|
+
db = await client.databases.create(
|
|
169
|
+
parent=parent_page,
|
|
170
|
+
title=title,
|
|
171
|
+
schema=schema_dict,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
result = format_success({
|
|
175
|
+
"id": db.id,
|
|
176
|
+
"title": db.title,
|
|
177
|
+
"url": db.url,
|
|
178
|
+
"properties_count": len(db.schema) if db.schema else 0,
|
|
179
|
+
})
|
|
180
|
+
typer.echo(result)
|
|
181
|
+
|
|
182
|
+
except typer.Exit:
|
|
183
|
+
raise
|
|
184
|
+
except Exception as e:
|
|
185
|
+
error_msg = str(e)
|
|
186
|
+
# Add helpful context for common errors
|
|
187
|
+
if "schema" in error_msg.lower():
|
|
188
|
+
error_msg += "\n\nHint: Use 'notion database-templates' to see schema examples or --template minimal for a simple database"
|
|
189
|
+
result = format_error("CREATE_ERROR", error_msg, retry=False)
|
|
190
|
+
typer.echo(result)
|
|
191
|
+
raise typer.Exit(code=1)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@app.command("database-templates")
|
|
195
|
+
def templates_cmd() -> None:
|
|
196
|
+
"""Show available database schema templates.
|
|
197
|
+
|
|
198
|
+
Examples:
|
|
199
|
+
notion database-templates
|
|
200
|
+
"""
|
|
201
|
+
typer.echo(json.dumps(SCHEMA_TEMPLATES, indent=2))
|
|
79
202
|
|
|
80
203
|
|
|
81
204
|
@app.command()
|