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.
@@ -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
- async def _create() -> str:
58
- try:
59
- client = get_client()
60
- parent_page = await client.pages.get(parent)
61
- schema_dict = json.loads(schema)
62
-
63
- db = await client.databases.create(
64
- parent=parent_page,
65
- title=title,
66
- schema=schema_dict,
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
- return format_success({
70
- "id": db.id,
71
- "title": db.title,
72
- "url": db.url,
73
- })
74
- except Exception as e:
75
- return format_error("UNKNOWN_ERROR", str(e), retry=False)
76
-
77
- result = asyncio.run(_create())
78
- typer.echo(result)
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()