Coverage for notion_client / api_endpoints.py: 100%
117 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-02 18:32 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-02 18:32 +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 "tab",
82 "table_of_contents",
83 "link_to_page",
84 "table_row",
85 "heading_1",
86 "heading_2",
87 "heading_3",
88 "heading_4",
89 "paragraph",
90 "bulleted_list_item",
91 "numbered_list_item",
92 "quote",
93 "to_do",
94 "toggle",
95 "template",
96 "callout",
97 "synced_block",
98 "table",
99 "column",
100 ),
101 auth=kwargs.get("auth"),
102 )
104 def delete(self, block_id: str, **kwargs: Any) -> SyncAsync[Any]:
105 """Set a [Block object](https://developers.notion.com/reference/block), including page blocks, to `archived: true`.
107 *[🔗 Endpoint documentation](https://developers.notion.com/reference/delete-a-block)*
108 """ # noqa: E501
109 return self.parent.request(
110 path=f"blocks/{block_id}",
111 method="DELETE",
112 auth=kwargs.get("auth"),
113 )
116class DatabasesEndpoint(Endpoint):
117 def retrieve(self, database_id: str, **kwargs: Any) -> SyncAsync[Any]:
118 """Retrieves a [database object](https://developers.notion.com/reference/database) for a provided database ID.
120 *[🔗 Endpoint documentation](https://developers.notion.com/reference/database-retrieve)*
121 """ # noqa: E501
122 return self.parent.request(
123 path=f"databases/{database_id}",
124 method="GET",
125 auth=kwargs.get("auth"),
126 )
128 def update(self, database_id: str, **kwargs: Any) -> SyncAsync[Any]:
129 """Update the title or properties of an existing database.
131 *[🔗 Endpoint documentation](https://developers.notion.com/reference/update-a-database)*
132 """ # noqa: E501
133 return self.parent.request(
134 path=f"databases/{database_id}",
135 method="PATCH",
136 body=pick(
137 kwargs,
138 "parent",
139 "title",
140 "description",
141 "is_inline",
142 "icon",
143 "cover",
144 "in_trash",
145 "is_locked",
146 ),
147 auth=kwargs.get("auth"),
148 )
150 def create(self, **kwargs: Any) -> SyncAsync[Any]:
151 """Create a new database.
153 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-database)*
154 """ # noqa: E501
155 return self.parent.request(
156 path="databases",
157 method="POST",
158 body=pick(
159 kwargs,
160 "parent",
161 "title",
162 "description",
163 "is_inline",
164 "initial_data_source",
165 "icon",
166 "cover",
167 ),
168 auth=kwargs.get("auth"),
169 )
172class DataSourcesEndpoint(Endpoint):
173 def retrieve(self, data_source_id: str, **kwargs: Any) -> SyncAsync[Any]:
174 """Retrieve a [data source](https://developers.notion.com/reference/data-source) object for a provided data source ID.
176 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-data-source)*
177 """ # noqa: E501
178 return self.parent.request(
179 path=f"data_sources/{data_source_id}", method="GET", auth=kwargs.get("auth")
180 )
182 def query(self, data_source_id: str, **kwargs: Any) -> SyncAsync[Any]:
183 """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.
185 *[🔗 Endpoint documentation](https://developers.notion.com/reference/query-a-data-source)*
186 """ # noqa: E501
187 return self.parent.request(
188 path=f"data_sources/{data_source_id}/query",
189 method="POST",
190 query=pick(kwargs, "filter_properties"),
191 body=pick(
192 kwargs,
193 "sorts",
194 "filter",
195 "start_cursor",
196 "page_size",
197 "archived",
198 "in_trash",
199 "result_type",
200 ),
201 auth=kwargs.get("auth"),
202 )
204 def create(self, **kwargs: Any) -> SyncAsync[Any]:
205 """Add an additional [data source](https://developers.notion.com/reference/data-source) to an existing [database](https://developers.notion.com/reference/database).
207 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-data-source)*
208 """ # noqa: E501
209 return self.parent.request(
210 path="data_sources",
211 method="POST",
212 body=pick(kwargs, "parent", "properties", "title", "icon"),
213 auth=kwargs.get("auth"),
214 )
216 def update(self, data_source_id: str, **kwargs: Any) -> SyncAsync[Any]:
217 """Updates the [data source](https://developers.notion.com/reference/data-source) object of a specified data source under a database.
219 *[🔗 Endpoint documentation](https://developers.notion.com/reference/update-a-data-source)*
220 """ # noqa: E501
221 return self.parent.request(
222 path=f"data_sources/{data_source_id}",
223 method="PATCH",
224 body=pick(
225 kwargs, "title", "icon", "properties", "in_trash", "archived", "parent"
226 ),
227 auth=kwargs.get("auth"),
228 )
230 def list_templates(self, data_source_id: str, **kwargs: Any) -> SyncAsync[Any]:
231 """List page templates that are available for a data source.
233 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-data-source-templates)*
234 """ # noqa: E501
235 return self.parent.request(
236 path=f"data_sources/{data_source_id}/templates",
237 method="GET",
238 query=pick(kwargs, "name", "start_cursor", "page_size"),
239 auth=kwargs.get("auth"),
240 )
243class PagesPropertiesEndpoint(Endpoint):
244 def retrieve(self, page_id: str, property_id: str, **kwargs: Any) -> SyncAsync[Any]:
245 """Retrieve a `property_item` object for a given `page_id` and `property_id`.
247 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-page-property)*
248 """ # noqa: E501
249 return self.parent.request(
250 path=f"pages/{page_id}/properties/{property_id}",
251 method="GET",
252 auth=kwargs.get("auth"),
253 query=pick(kwargs, "start_cursor", "page_size"),
254 )
257class PagesEndpoint(Endpoint):
258 def __init__(self, *args: Any, **kwargs: Any) -> None:
259 super().__init__(*args, **kwargs)
260 self.properties = PagesPropertiesEndpoint(*args, **kwargs)
262 def create(self, **kwargs: Any) -> SyncAsync[Any]:
263 """Create a new page in the specified database or as a child of an existing page.
265 *[🔗 Endpoint documentation](https://developers.notion.com/reference/post-page)*
266 """ # noqa: E501
267 return self.parent.request(
268 path="pages",
269 method="POST",
270 body=pick(
271 kwargs,
272 "parent",
273 "properties",
274 "icon",
275 "cover",
276 "content",
277 "children",
278 "markdown",
279 "template",
280 "position",
281 ),
282 auth=kwargs.get("auth"),
283 )
285 def retrieve(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
286 """Retrieve a [Page object](https://developers.notion.com/reference/page) using the ID specified.
288 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-page)*
289 """ # noqa: E501
290 return self.parent.request(
291 path=f"pages/{page_id}",
292 method="GET",
293 query=pick(kwargs, "filter_properties"),
294 auth=kwargs.get("auth"),
295 )
297 def update(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
298 """Update [page property values](https://developers.notion.com/reference/page#property-value-object) for the specified page.
300 *[🔗 Endpoint documentation](https://developers.notion.com/reference/patch-page)*
301 """ # noqa: E501
302 return self.parent.request(
303 path=f"pages/{page_id}",
304 method="PATCH",
305 body=pick(
306 kwargs,
307 "properties",
308 "icon",
309 "cover",
310 "is_locked",
311 "template",
312 "erase_content",
313 "archived",
314 "in_trash",
315 ),
316 auth=kwargs.get("auth"),
317 )
319 def retrieve_markdown(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
320 """Retrieve a page as markdown.
322 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-page-markdown)*
323 """ # noqa: E501
324 return self.parent.request(
325 path=f"pages/{page_id}/markdown",
326 method="GET",
327 query=pick(kwargs, "include_transcript"),
328 auth=kwargs.get("auth"),
329 )
331 def update_markdown(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
332 """Update a page's content as markdown.
334 *[🔗 Endpoint documentation](https://developers.notion.com/reference/update-page-markdown)*
335 """ # noqa: E501
336 return self.parent.request(
337 path=f"pages/{page_id}/markdown",
338 method="PATCH",
339 body=pick(
340 kwargs,
341 "type",
342 "insert_content",
343 "replace_content_range",
344 "update_content",
345 "replace_content",
346 ),
347 auth=kwargs.get("auth"),
348 )
350 def move(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
351 """Use this API to move an existing Notion page to a new parent.
353 *[🔗 Endpoint documentation](https://developers.notion.com/reference/move-page)*
354 """ # noqa: E501
355 return self.parent.request(
356 path=f"pages/{page_id}/move",
357 method="POST",
358 body=pick(kwargs, "parent"),
359 auth=kwargs.get("auth"),
360 )
363class UsersEndpoint(Endpoint):
364 def list(self, **kwargs: Any) -> SyncAsync[Any]:
365 """Return a paginated list of [Users](https://developers.notion.com/reference/user) for the workspace.
367 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-users)*
368 """ # noqa: E501
369 return self.parent.request(
370 path="users",
371 method="GET",
372 query=pick(kwargs, "start_cursor", "page_size"),
373 auth=kwargs.get("auth"),
374 )
376 def retrieve(self, user_id: str, **kwargs: Any) -> SyncAsync[Any]:
377 """Retrieve a [User](https://developers.notion.com/reference/user) using the ID specified.
379 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-user)*
380 """ # noqa: E501
381 return self.parent.request(
382 path=f"users/{user_id}", method="GET", auth=kwargs.get("auth")
383 )
385 def me(self, **kwargs: Any) -> SyncAsync[Any]:
386 """Retrieve the bot [User](https://developers.notion.com/reference/user) associated with the API token.
388 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-self)*
389 """ # noqa: E501
390 return self.parent.request(
391 path="users/me", method="GET", auth=kwargs.get("auth")
392 )
395class ViewsQueriesEndpoint(Endpoint):
396 def create(self, view_id: str, **kwargs: Any) -> SyncAsync[Any]:
397 """Create a view query.
399 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-view-query)*
400 """ # noqa: E501
401 return self.parent.request(
402 path=f"views/{view_id}/queries",
403 method="POST",
404 body=pick(kwargs, "page_size"),
405 auth=kwargs.get("auth"),
406 )
408 def results(self, view_id: str, query_id: str, **kwargs: Any) -> SyncAsync[Any]:
409 """Get view query results.
411 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-view-query-results)*
412 """ # noqa: E501
413 return self.parent.request(
414 path=f"views/{view_id}/queries/{query_id}",
415 method="GET",
416 query=pick(kwargs, "start_cursor", "page_size"),
417 auth=kwargs.get("auth"),
418 )
420 def delete(self, view_id: str, query_id: str, **kwargs: Any) -> SyncAsync[Any]:
421 """Delete a view query.
423 *[🔗 Endpoint documentation](https://developers.notion.com/reference/delete-view-query)*
424 """ # noqa: E501
425 return self.parent.request(
426 path=f"views/{view_id}/queries/{query_id}",
427 method="DELETE",
428 auth=kwargs.get("auth"),
429 )
432class ViewsEndpoint(Endpoint):
433 def __init__(self, *args: Any, **kwargs: Any) -> None:
434 super().__init__(*args, **kwargs)
435 self.queries = ViewsQueriesEndpoint(*args, **kwargs)
437 def create(self, **kwargs: Any) -> SyncAsync[Any]:
438 """Create a view.
440 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-view)*
441 """ # noqa: E501
442 return self.parent.request(
443 path="views",
444 method="POST",
445 body=pick(
446 kwargs,
447 "data_source_id",
448 "name",
449 "type",
450 "database_id",
451 "view_id",
452 "filter",
453 "sorts",
454 "quick_filters",
455 "create_database",
456 "configuration",
457 "position",
458 "placement",
459 ),
460 auth=kwargs.get("auth"),
461 )
463 def retrieve(self, view_id: str, **kwargs: Any) -> SyncAsync[Any]:
464 """Retrieve a view.
466 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-view)*
467 """ # noqa: E501
468 return self.parent.request(
469 path=f"views/{view_id}",
470 method="GET",
471 auth=kwargs.get("auth"),
472 )
474 def update(self, view_id: str, **kwargs: Any) -> SyncAsync[Any]:
475 """Update a view.
477 *[🔗 Endpoint documentation](https://developers.notion.com/reference/update-a-view)*
478 """ # noqa: E501
479 return self.parent.request(
480 path=f"views/{view_id}",
481 method="PATCH",
482 body=pick(
483 kwargs,
484 "name",
485 "filter",
486 "sorts",
487 "quick_filters",
488 "configuration",
489 ),
490 auth=kwargs.get("auth"),
491 )
493 def delete(self, view_id: str, **kwargs: Any) -> SyncAsync[Any]:
494 """Delete a view.
496 *[🔗 Endpoint documentation](https://developers.notion.com/reference/delete-view)*
497 """ # noqa: E501
498 return self.parent.request(
499 path=f"views/{view_id}",
500 method="DELETE",
501 auth=kwargs.get("auth"),
502 )
504 def list(self, **kwargs: Any) -> SyncAsync[Any]:
505 """List views for a database.
507 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-views)*
508 """ # noqa: E501
509 return self.parent.request(
510 path="views",
511 method="GET",
512 query=pick(
513 kwargs, "database_id", "data_source_id", "start_cursor", "page_size"
514 ),
515 auth=kwargs.get("auth"),
516 )
519class SearchEndpoint(Endpoint):
520 def __call__(self, **kwargs: Any) -> SyncAsync[Any]:
521 """Search all pages and child pages that are shared with the integration.
523 *[🔗 Endpoint documentation](https://developers.notion.com/reference/post-search)*
524 """ # noqa: E501
525 return self.parent.request(
526 path="search",
527 method="POST",
528 body=pick(kwargs, "query", "sort", "filter", "start_cursor", "page_size"),
529 auth=kwargs.get("auth"),
530 )
533class CustomEmojisEndpoint(Endpoint):
534 def list(self, **kwargs: Any) -> SyncAsync[Any]:
535 """List custom emojis.
537 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-custom-emojis)*
538 """ # noqa: E501
539 return self.parent.request(
540 path="custom_emojis",
541 method="GET",
542 query=pick(kwargs, "start_cursor", "page_size", "name"),
543 auth=kwargs.get("auth"),
544 )
547class CommentsEndpoint(Endpoint):
548 def create(self, **kwargs: Any) -> SyncAsync[Any]:
549 """Create a new comment in the specified page or existing discussion thread.
551 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-comment)*
552 """ # noqa: E501
553 return self.parent.request(
554 path="comments",
555 method="POST",
556 body=pick(
557 kwargs,
558 "rich_text",
559 "attachments",
560 "display_name",
561 "parent",
562 "discussion_id",
563 ),
564 auth=kwargs.get("auth"),
565 )
567 def list(self, **kwargs: Any) -> SyncAsync[Any]:
568 """Retrieve a list of un-resolved [Comment objects](https://developers.notion.com/reference/comment-object) from the specified block.
570 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-comments)*
571 """ # noqa: E501
572 return self.parent.request(
573 path="comments",
574 method="GET",
575 query=pick(kwargs, "block_id", "start_cursor", "page_size"),
576 auth=kwargs.get("auth"),
577 )
579 def retrieve(self, comment_id: str, **kwargs: Any) -> SyncAsync[Any]:
580 """Retrieve a [Comment object](https://developers.notion.com/reference/comment-object) from its `comment_id`.
582 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-comment)*
583 """ # noqa: E501
584 return self.parent.request(
585 path=f"comments/{comment_id}",
586 method="GET",
587 auth=kwargs.get("auth"),
588 )
591class FileUploadsEndpoint(Endpoint):
592 def create(self, **kwargs: Any) -> SyncAsync[Any]:
593 """Create a file upload.
595 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-file-upload)*
596 """ # noqa: E501
597 return self.parent.request(
598 path="file_uploads",
599 method="POST",
600 body=pick(
601 kwargs,
602 "mode",
603 "filename",
604 "content_type",
605 "number_of_parts",
606 "external_url",
607 ),
608 auth=kwargs.get("auth"),
609 )
611 def complete(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]:
612 """Complete the file upload process.
614 *[🔗 Endpoint documentation](https://developers.notion.com/reference/complete-a-file-upload)*
615 """ # noqa: E501
616 return self.parent.request(
617 path=f"file_uploads/{file_upload_id}/complete",
618 method="POST",
619 auth=kwargs.get("auth"),
620 )
622 def retrieve(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]:
623 """Retrieve a file upload object using the ID specified.
625 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-file-upload)*
626 """ # noqa: E501
627 return self.parent.request(
628 path=f"file_uploads/{file_upload_id}",
629 method="GET",
630 auth=kwargs.get("auth"),
631 )
633 def list(self, **kwargs: Any) -> SyncAsync[Any]:
634 """List all file uploads.
636 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-file-uploads)*
637 """ # noqa: E501
638 return self.parent.request(
639 path="file_uploads",
640 method="GET",
641 query=pick(kwargs, "status", "start_cursor", "page_size"),
642 auth=kwargs.get("auth"),
643 )
645 def send(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]:
646 """Send a file upload
648 *[🔗 Endpoint documentation](https://developers.notion.com/reference/send-a-file-upload)*
649 """ # noqa: E501
650 return self.parent.request(
651 path=f"file_uploads/{file_upload_id}/send",
652 method="POST",
653 form_data=pick(kwargs, "file", "part_number"),
654 auth=kwargs.get("auth"),
655 )
658class OAuthEndpoint(Endpoint):
659 def token(
660 self, client_id: str, client_secret: str, **kwargs: Any
661 ) -> SyncAsync[Any]:
662 """Create an access token that a third-party service can use to authenticate with Notion.
664 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-token)*
665 """ # noqa: E501
666 return self.parent.request(
667 path="oauth/token",
668 method="POST",
669 body=pick(
670 kwargs,
671 "grant_type",
672 "code",
673 "redirect_uri",
674 "external_account",
675 "refresh_token",
676 ),
677 auth={"client_id": client_id, "client_secret": client_secret},
678 )
680 def introspect(
681 self, client_id: str, client_secret: str, **kwargs: Any
682 ) -> SyncAsync[Any]:
683 """Get a token's active status, scope, and issued time.
685 *[🔗 Endpoint documentation](https://developers.notion.com/reference/introspect-token)*
686 """ # noqa: E501
687 return self.parent.request(
688 path="oauth/introspect",
689 method="POST",
690 body=pick(kwargs, "token"),
691 auth={"client_id": client_id, "client_secret": client_secret},
692 )
694 def revoke(
695 self, client_id: str, client_secret: str, **kwargs: Any
696 ) -> SyncAsync[Any]:
697 """Revoke an access token.
699 *[🔗 Endpoint documentation](https://developers.notion.com/reference/revoke-token)*
700 """ # noqa: E501
701 return self.parent.request(
702 path="oauth/revoke",
703 method="POST",
704 body=pick(kwargs, "token"),
705 auth={"client_id": client_id, "client_secret": client_secret},
706 )