Coverage for notion_client / api_endpoints.py: 100%
89 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-23 09:42 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-23 09:42 +0000
1"""Notion API endpoints.""" # noqa: E501
3from typing import TYPE_CHECKING, Any
5from notion_client.helpers import pick
6from notion_client.typing import SyncAsync
8if TYPE_CHECKING: # pragma: no cover
9 from notion_client.client import BaseClient
12class Endpoint:
13 def __init__(self, parent: "BaseClient") -> None:
14 self.parent = parent
17class BlocksChildrenEndpoint(Endpoint):
18 def append(self, block_id: str, **kwargs: Any) -> SyncAsync[Any]:
19 """Create and append new children blocks to the block using the ID specified.
21 *[🔗 Endpoint documentation](https://developers.notion.com/reference/patch-block-children)*
22 """ # noqa: E501
23 return self.parent.request(
24 path=f"blocks/{block_id}/children",
25 method="PATCH",
26 body=pick(kwargs, "children", "after", "position"),
27 auth=kwargs.get("auth"),
28 )
30 def list(self, block_id: str, **kwargs: Any) -> SyncAsync[Any]:
31 """Return a paginated array of child [block objects](https://developers.notion.com/reference/block) contained in the block.
33 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-block-children)*
34 """ # noqa: E501
35 return self.parent.request(
36 path=f"blocks/{block_id}/children",
37 method="GET",
38 query=pick(kwargs, "start_cursor", "page_size"),
39 auth=kwargs.get("auth"),
40 )
43class BlocksEndpoint(Endpoint):
44 def __init__(self, *args: Any, **kwargs: Any) -> None:
45 super().__init__(*args, **kwargs)
46 self.children = BlocksChildrenEndpoint(*args, **kwargs)
48 def retrieve(self, block_id: str, **kwargs: Any) -> SyncAsync[Any]:
49 """Retrieve a [Block object](https://developers.notion.com/reference/block) using the ID specified.
51 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-block)*
52 """ # noqa: E501
53 return self.parent.request(
54 path=f"blocks/{block_id}", method="GET", auth=kwargs.get("auth")
55 )
57 def update(self, block_id: str, **kwargs: Any) -> SyncAsync[Any]:
58 """Update the content for the specified `block_id` based on the block type.
60 *[🔗 Endpoint documentation](https://developers.notion.com/reference/update-a-block)*
61 """ # noqa: E501
62 return self.parent.request(
63 path=f"blocks/{block_id}",
64 method="PATCH",
65 body=pick(
66 kwargs,
67 "embed",
68 "type",
69 "archived",
70 "in_trash",
71 "bookmark",
72 "image",
73 "video",
74 "pdf",
75 "file",
76 "audio",
77 "code",
78 "equation",
79 "divider",
80 "breadcrumb",
81 "table_of_contents",
82 "link_to_page",
83 "table_row",
84 "heading_1",
85 "heading_2",
86 "heading_3",
87 "paragraph",
88 "bulleted_list_item",
89 "numbered_list_item",
90 "quote",
91 "to_do",
92 "toggle",
93 "template",
94 "callout",
95 "synced_block",
96 "table",
97 "column",
98 ),
99 auth=kwargs.get("auth"),
100 )
102 def delete(self, block_id: str, **kwargs: Any) -> SyncAsync[Any]:
103 """Set a [Block object](https://developers.notion.com/reference/block), including page blocks, to `archived: true`.
105 *[🔗 Endpoint documentation](https://developers.notion.com/reference/delete-a-block)*
106 """ # noqa: E501
107 return self.parent.request(
108 path=f"blocks/{block_id}",
109 method="DELETE",
110 auth=kwargs.get("auth"),
111 )
114class DatabasesEndpoint(Endpoint):
115 def retrieve(self, database_id: str, **kwargs: Any) -> SyncAsync[Any]:
116 """Retrieves a [database object](https://developers.notion.com/reference/database) for a provided database ID.
118 *[🔗 Endpoint documentation](https://developers.notion.com/reference/database-retrieve)*
119 """ # noqa: E501
120 return self.parent.request(
121 path=f"databases/{database_id}",
122 method="GET",
123 auth=kwargs.get("auth"),
124 )
126 def update(self, database_id: str, **kwargs: Any) -> SyncAsync[Any]:
127 """Update the title or properties of an existing database.
129 *[🔗 Endpoint documentation](https://developers.notion.com/reference/update-a-database)*
130 """ # noqa: E501
131 return self.parent.request(
132 path=f"databases/{database_id}",
133 method="PATCH",
134 body=pick(
135 kwargs,
136 "parent",
137 "title",
138 "description",
139 "is_inline",
140 "icon",
141 "cover",
142 "in_trash",
143 "is_locked",
144 ),
145 auth=kwargs.get("auth"),
146 )
148 def create(self, **kwargs: Any) -> SyncAsync[Any]:
149 """Create a new database.
151 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-database)*
152 """ # noqa: E501
153 return self.parent.request(
154 path="databases",
155 method="POST",
156 body=pick(
157 kwargs,
158 "parent",
159 "title",
160 "description",
161 "is_inline",
162 "initial_data_source",
163 "icon",
164 "cover",
165 ),
166 auth=kwargs.get("auth"),
167 )
170class DataSourcesEndpoint(Endpoint):
171 def retrieve(self, data_source_id: str, **kwargs: Any) -> SyncAsync[Any]:
172 """Retrieve a [data source](https://developers.notion.com/reference/data-source) object for a provided data source ID.
174 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-data-source)*
175 """ # noqa: E501
176 return self.parent.request(
177 path=f"data_sources/{data_source_id}", method="GET", auth=kwargs.get("auth")
178 )
180 def query(self, data_source_id: str, **kwargs: Any) -> SyncAsync[Any]:
181 """Get a list of [Pages](https://developers.notion.com/reference/page) and/or [Data Sources](https://developers.notion.com/reference/data-source) contained in the data source.
183 *[🔗 Endpoint documentation](https://developers.notion.com/reference/query-a-data-source)*
184 """ # noqa: E501
185 return self.parent.request(
186 path=f"data_sources/{data_source_id}/query",
187 method="POST",
188 query=pick(kwargs, "filter_properties"),
189 body=pick(
190 kwargs,
191 "sorts",
192 "filter",
193 "start_cursor",
194 "page_size",
195 "archived",
196 "in_trash",
197 "result_type",
198 ),
199 auth=kwargs.get("auth"),
200 )
202 def create(self, **kwargs: Any) -> SyncAsync[Any]:
203 """Add an additional [data source](https://developers.notion.com/reference/data-source) to an existing [database](https://developers.notion.com/reference/database).
205 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-data-source)*
206 """ # noqa: E501
207 return self.parent.request(
208 path="data_sources",
209 method="POST",
210 body=pick(kwargs, "parent", "properties", "title", "icon"),
211 auth=kwargs.get("auth"),
212 )
214 def update(self, data_source_id: str, **kwargs: Any) -> SyncAsync[Any]:
215 """Updates the [data source](https://developers.notion.com/reference/data-source) object of a specified data source under a database.
217 *[🔗 Endpoint documentation](https://developers.notion.com/reference/update-a-data-source)*
218 """ # noqa: E501
219 return self.parent.request(
220 path=f"data_sources/{data_source_id}",
221 method="PATCH",
222 body=pick(
223 kwargs, "title", "icon", "properties", "in_trash", "archived", "parent"
224 ),
225 auth=kwargs.get("auth"),
226 )
228 def list_templates(self, data_source_id: str, **kwargs: Any) -> SyncAsync[Any]:
229 """List page templates that are available for a data source.
231 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-data-source-templates)*
232 """ # noqa: E501
233 return self.parent.request(
234 path=f"data_sources/{data_source_id}/templates",
235 method="GET",
236 query=pick(kwargs, "name", "start_cursor", "page_size"),
237 auth=kwargs.get("auth"),
238 )
241class PagesPropertiesEndpoint(Endpoint):
242 def retrieve(self, page_id: str, property_id: str, **kwargs: Any) -> SyncAsync[Any]:
243 """Retrieve a `property_item` object for a given `page_id` and `property_id`.
245 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-page-property)*
246 """ # noqa: E501
247 return self.parent.request(
248 path=f"pages/{page_id}/properties/{property_id}",
249 method="GET",
250 auth=kwargs.get("auth"),
251 query=pick(kwargs, "start_cursor", "page_size"),
252 )
255class PagesEndpoint(Endpoint):
256 def __init__(self, *args: Any, **kwargs: Any) -> None:
257 super().__init__(*args, **kwargs)
258 self.properties = PagesPropertiesEndpoint(*args, **kwargs)
260 def create(self, **kwargs: Any) -> SyncAsync[Any]:
261 """Create a new page in the specified database or as a child of an existing page.
263 *[🔗 Endpoint documentation](https://developers.notion.com/reference/post-page)*
264 """ # noqa: E501
265 return self.parent.request(
266 path="pages",
267 method="POST",
268 body=pick(
269 kwargs,
270 "parent",
271 "properties",
272 "icon",
273 "cover",
274 "content",
275 "children",
276 "template",
277 "position",
278 ),
279 auth=kwargs.get("auth"),
280 )
282 def retrieve(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
283 """Retrieve a [Page object](https://developers.notion.com/reference/page) using the ID specified.
285 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-page)*
286 """ # noqa: E501
287 return self.parent.request(
288 path=f"pages/{page_id}",
289 method="GET",
290 query=pick(kwargs, "filter_properties"),
291 auth=kwargs.get("auth"),
292 )
294 def update(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
295 """Update [page property values](https://developers.notion.com/reference/page#property-value-object) for the specified page.
297 *[🔗 Endpoint documentation](https://developers.notion.com/reference/patch-page)*
298 """ # noqa: E501
299 return self.parent.request(
300 path=f"pages/{page_id}",
301 method="PATCH",
302 body=pick(
303 kwargs,
304 "properties",
305 "icon",
306 "cover",
307 "is_locked",
308 "template",
309 "erase_content",
310 "archived",
311 "in_trash",
312 ),
313 auth=kwargs.get("auth"),
314 )
316 def move(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
317 """Use this API to move an existing Notion page to a new parent.
319 *[🔗 Endpoint documentation](https://developers.notion.com/reference/move-page)*
320 """ # noqa: E501
321 return self.parent.request(
322 path=f"pages/{page_id}/move",
323 method="POST",
324 body=pick(kwargs, "parent"),
325 auth=kwargs.get("auth"),
326 )
329class UsersEndpoint(Endpoint):
330 def list(self, **kwargs: Any) -> SyncAsync[Any]:
331 """Return a paginated list of [Users](https://developers.notion.com/reference/user) for the workspace.
333 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-users)*
334 """ # noqa: E501
335 return self.parent.request(
336 path="users",
337 method="GET",
338 query=pick(kwargs, "start_cursor", "page_size"),
339 auth=kwargs.get("auth"),
340 )
342 def retrieve(self, user_id: str, **kwargs: Any) -> SyncAsync[Any]:
343 """Retrieve a [User](https://developers.notion.com/reference/user) using the ID specified.
345 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-user)*
346 """ # noqa: E501
347 return self.parent.request(
348 path=f"users/{user_id}", method="GET", auth=kwargs.get("auth")
349 )
351 def me(self, **kwargs: Any) -> SyncAsync[Any]:
352 """Retrieve the bot [User](https://developers.notion.com/reference/user) associated with the API token.
354 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-self)*
355 """ # noqa: E501
356 return self.parent.request(
357 path="users/me", method="GET", auth=kwargs.get("auth")
358 )
361class SearchEndpoint(Endpoint):
362 def __call__(self, **kwargs: Any) -> SyncAsync[Any]:
363 """Search all pages and child pages that are shared with the integration.
365 *[🔗 Endpoint documentation](https://developers.notion.com/reference/post-search)*
366 """ # noqa: E501
367 return self.parent.request(
368 path="search",
369 method="POST",
370 body=pick(kwargs, "query", "sort", "filter", "start_cursor", "page_size"),
371 auth=kwargs.get("auth"),
372 )
375class CommentsEndpoint(Endpoint):
376 def create(self, **kwargs: Any) -> SyncAsync[Any]:
377 """Create a new comment in the specified page or existing discussion thread.
379 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-comment)*
380 """ # noqa: E501
381 return self.parent.request(
382 path="comments",
383 method="POST",
384 body=pick(
385 kwargs,
386 "rich_text",
387 "attachments",
388 "display_name",
389 "parent",
390 "discussion_id",
391 ),
392 auth=kwargs.get("auth"),
393 )
395 def list(self, **kwargs: Any) -> SyncAsync[Any]:
396 """Retrieve a list of un-resolved [Comment objects](https://developers.notion.com/reference/comment-object) from the specified block.
398 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-comments)*
399 """ # noqa: E501
400 return self.parent.request(
401 path="comments",
402 method="GET",
403 query=pick(kwargs, "block_id", "start_cursor", "page_size"),
404 auth=kwargs.get("auth"),
405 )
407 def retrieve(self, comment_id: str, **kwargs: Any) -> SyncAsync[Any]:
408 """Retrieve a [Comment object](https://developers.notion.com/reference/comment-object) from its `comment_id`.
410 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-comment)*
411 """ # noqa: E501
412 return self.parent.request(
413 path=f"comments/{comment_id}",
414 method="GET",
415 auth=kwargs.get("auth"),
416 )
419class FileUploadsEndpoint(Endpoint):
420 def create(self, **kwargs: Any) -> SyncAsync[Any]:
421 """Create a file upload.
423 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-file-upload)*
424 """ # noqa: E501
425 return self.parent.request(
426 path="file_uploads",
427 method="POST",
428 body=pick(
429 kwargs,
430 "mode",
431 "filename",
432 "content_type",
433 "number_of_parts",
434 "external_url",
435 ),
436 auth=kwargs.get("auth"),
437 )
439 def complete(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]:
440 """Complete the file upload process.
442 *[🔗 Endpoint documentation](https://developers.notion.com/reference/complete-a-file-upload)*
443 """ # noqa: E501
444 return self.parent.request(
445 path=f"file_uploads/{file_upload_id}/complete",
446 method="POST",
447 auth=kwargs.get("auth"),
448 )
450 def retrieve(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]:
451 """Retrieve a file upload object using the ID specified.
453 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-file-upload)*
454 """ # noqa: E501
455 return self.parent.request(
456 path=f"file_uploads/{file_upload_id}",
457 method="GET",
458 auth=kwargs.get("auth"),
459 )
461 def list(self, **kwargs: Any) -> SyncAsync[Any]:
462 """List all file uploads.
464 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-file-uploads)*
465 """ # noqa: E501
466 return self.parent.request(
467 path="file_uploads",
468 method="GET",
469 query=pick(kwargs, "status", "start_cursor", "page_size"),
470 auth=kwargs.get("auth"),
471 )
473 def send(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]:
474 """Send a file upload
476 *[🔗 Endpoint documentation](https://developers.notion.com/reference/send-a-file-upload)*
477 """ # noqa: E501
478 return self.parent.request(
479 path=f"file_uploads/{file_upload_id}/send",
480 method="POST",
481 form_data=pick(kwargs, "file", "part_number"),
482 auth=kwargs.get("auth"),
483 )
486class OAuthEndpoint(Endpoint):
487 def token(
488 self, client_id: str, client_secret: str, **kwargs: Any
489 ) -> SyncAsync[Any]:
490 """Create an access token that a third-party service can use to authenticate with Notion.
492 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-token)*
493 """ # noqa: E501
494 return self.parent.request(
495 path="oauth/token",
496 method="POST",
497 body=pick(
498 kwargs,
499 "grant_type",
500 "code",
501 "redirect_uri",
502 "external_account",
503 "refresh_token",
504 ),
505 auth={"client_id": client_id, "client_secret": client_secret},
506 )
508 def introspect(
509 self, client_id: str, client_secret: str, **kwargs: Any
510 ) -> SyncAsync[Any]:
511 """Get a token's active status, scope, and issued time.
513 *[🔗 Endpoint documentation](https://developers.notion.com/reference/introspect-token)*
514 """ # noqa: E501
515 return self.parent.request(
516 path="oauth/introspect",
517 method="POST",
518 body=pick(kwargs, "token"),
519 auth={"client_id": client_id, "client_secret": client_secret},
520 )
522 def revoke(
523 self, client_id: str, client_secret: str, **kwargs: Any
524 ) -> SyncAsync[Any]:
525 """Revoke an access token.
527 *[🔗 Endpoint documentation](https://developers.notion.com/reference/revoke-token)*
528 """ # noqa: E501
529 return self.parent.request(
530 path="oauth/revoke",
531 method="POST",
532 body=pick(kwargs, "token"),
533 auth={"client_id": client_id, "client_secret": client_secret},
534 )