Coverage for notion_client / api_endpoints.py: 100%
93 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-17 21:35 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-17 21:35 +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 "markdown",
277 "template",
278 "position",
279 ),
280 auth=kwargs.get("auth"),
281 )
283 def retrieve(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
284 """Retrieve a [Page object](https://developers.notion.com/reference/page) using the ID specified.
286 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-page)*
287 """ # noqa: E501
288 return self.parent.request(
289 path=f"pages/{page_id}",
290 method="GET",
291 query=pick(kwargs, "filter_properties"),
292 auth=kwargs.get("auth"),
293 )
295 def update(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
296 """Update [page property values](https://developers.notion.com/reference/page#property-value-object) for the specified page.
298 *[🔗 Endpoint documentation](https://developers.notion.com/reference/patch-page)*
299 """ # noqa: E501
300 return self.parent.request(
301 path=f"pages/{page_id}",
302 method="PATCH",
303 body=pick(
304 kwargs,
305 "properties",
306 "icon",
307 "cover",
308 "is_locked",
309 "template",
310 "erase_content",
311 "archived",
312 "in_trash",
313 ),
314 auth=kwargs.get("auth"),
315 )
317 def retrieve_markdown(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
318 """Retrieve a page as markdown.
320 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-page-markdown)*
321 """ # noqa: E501
322 return self.parent.request(
323 path=f"pages/{page_id}/markdown",
324 method="GET",
325 query=pick(kwargs, "include_transcript"),
326 auth=kwargs.get("auth"),
327 )
329 def update_markdown(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
330 """Update a page's content as markdown.
332 *[🔗 Endpoint documentation](https://developers.notion.com/reference/update-page-markdown)*
333 """ # noqa: E501
334 return self.parent.request(
335 path=f"pages/{page_id}/markdown",
336 method="PATCH",
337 body=pick(kwargs, "type", "insert_content", "replace_content_range"),
338 auth=kwargs.get("auth"),
339 )
341 def move(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]:
342 """Use this API to move an existing Notion page to a new parent.
344 *[🔗 Endpoint documentation](https://developers.notion.com/reference/move-page)*
345 """ # noqa: E501
346 return self.parent.request(
347 path=f"pages/{page_id}/move",
348 method="POST",
349 body=pick(kwargs, "parent"),
350 auth=kwargs.get("auth"),
351 )
354class UsersEndpoint(Endpoint):
355 def list(self, **kwargs: Any) -> SyncAsync[Any]:
356 """Return a paginated list of [Users](https://developers.notion.com/reference/user) for the workspace.
358 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-users)*
359 """ # noqa: E501
360 return self.parent.request(
361 path="users",
362 method="GET",
363 query=pick(kwargs, "start_cursor", "page_size"),
364 auth=kwargs.get("auth"),
365 )
367 def retrieve(self, user_id: str, **kwargs: Any) -> SyncAsync[Any]:
368 """Retrieve a [User](https://developers.notion.com/reference/user) using the ID specified.
370 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-user)*
371 """ # noqa: E501
372 return self.parent.request(
373 path=f"users/{user_id}", method="GET", auth=kwargs.get("auth")
374 )
376 def me(self, **kwargs: Any) -> SyncAsync[Any]:
377 """Retrieve the bot [User](https://developers.notion.com/reference/user) associated with the API token.
379 *[🔗 Endpoint documentation](https://developers.notion.com/reference/get-self)*
380 """ # noqa: E501
381 return self.parent.request(
382 path="users/me", method="GET", auth=kwargs.get("auth")
383 )
386class SearchEndpoint(Endpoint):
387 def __call__(self, **kwargs: Any) -> SyncAsync[Any]:
388 """Search all pages and child pages that are shared with the integration.
390 *[🔗 Endpoint documentation](https://developers.notion.com/reference/post-search)*
391 """ # noqa: E501
392 return self.parent.request(
393 path="search",
394 method="POST",
395 body=pick(kwargs, "query", "sort", "filter", "start_cursor", "page_size"),
396 auth=kwargs.get("auth"),
397 )
400class CommentsEndpoint(Endpoint):
401 def create(self, **kwargs: Any) -> SyncAsync[Any]:
402 """Create a new comment in the specified page or existing discussion thread.
404 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-comment)*
405 """ # noqa: E501
406 return self.parent.request(
407 path="comments",
408 method="POST",
409 body=pick(
410 kwargs,
411 "rich_text",
412 "attachments",
413 "display_name",
414 "parent",
415 "discussion_id",
416 ),
417 auth=kwargs.get("auth"),
418 )
420 def list(self, **kwargs: Any) -> SyncAsync[Any]:
421 """Retrieve a list of un-resolved [Comment objects](https://developers.notion.com/reference/comment-object) from the specified block.
423 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-comments)*
424 """ # noqa: E501
425 return self.parent.request(
426 path="comments",
427 method="GET",
428 query=pick(kwargs, "block_id", "start_cursor", "page_size"),
429 auth=kwargs.get("auth"),
430 )
432 def retrieve(self, comment_id: str, **kwargs: Any) -> SyncAsync[Any]:
433 """Retrieve a [Comment object](https://developers.notion.com/reference/comment-object) from its `comment_id`.
435 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-comment)*
436 """ # noqa: E501
437 return self.parent.request(
438 path=f"comments/{comment_id}",
439 method="GET",
440 auth=kwargs.get("auth"),
441 )
444class FileUploadsEndpoint(Endpoint):
445 def create(self, **kwargs: Any) -> SyncAsync[Any]:
446 """Create a file upload.
448 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-file-upload)*
449 """ # noqa: E501
450 return self.parent.request(
451 path="file_uploads",
452 method="POST",
453 body=pick(
454 kwargs,
455 "mode",
456 "filename",
457 "content_type",
458 "number_of_parts",
459 "external_url",
460 ),
461 auth=kwargs.get("auth"),
462 )
464 def complete(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]:
465 """Complete the file upload process.
467 *[🔗 Endpoint documentation](https://developers.notion.com/reference/complete-a-file-upload)*
468 """ # noqa: E501
469 return self.parent.request(
470 path=f"file_uploads/{file_upload_id}/complete",
471 method="POST",
472 auth=kwargs.get("auth"),
473 )
475 def retrieve(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]:
476 """Retrieve a file upload object using the ID specified.
478 *[🔗 Endpoint documentation](https://developers.notion.com/reference/retrieve-a-file-upload)*
479 """ # noqa: E501
480 return self.parent.request(
481 path=f"file_uploads/{file_upload_id}",
482 method="GET",
483 auth=kwargs.get("auth"),
484 )
486 def list(self, **kwargs: Any) -> SyncAsync[Any]:
487 """List all file uploads.
489 *[🔗 Endpoint documentation](https://developers.notion.com/reference/list-file-uploads)*
490 """ # noqa: E501
491 return self.parent.request(
492 path="file_uploads",
493 method="GET",
494 query=pick(kwargs, "status", "start_cursor", "page_size"),
495 auth=kwargs.get("auth"),
496 )
498 def send(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]:
499 """Send a file upload
501 *[🔗 Endpoint documentation](https://developers.notion.com/reference/send-a-file-upload)*
502 """ # noqa: E501
503 return self.parent.request(
504 path=f"file_uploads/{file_upload_id}/send",
505 method="POST",
506 form_data=pick(kwargs, "file", "part_number"),
507 auth=kwargs.get("auth"),
508 )
511class OAuthEndpoint(Endpoint):
512 def token(
513 self, client_id: str, client_secret: str, **kwargs: Any
514 ) -> SyncAsync[Any]:
515 """Create an access token that a third-party service can use to authenticate with Notion.
517 *[🔗 Endpoint documentation](https://developers.notion.com/reference/create-a-token)*
518 """ # noqa: E501
519 return self.parent.request(
520 path="oauth/token",
521 method="POST",
522 body=pick(
523 kwargs,
524 "grant_type",
525 "code",
526 "redirect_uri",
527 "external_account",
528 "refresh_token",
529 ),
530 auth={"client_id": client_id, "client_secret": client_secret},
531 )
533 def introspect(
534 self, client_id: str, client_secret: str, **kwargs: Any
535 ) -> SyncAsync[Any]:
536 """Get a token's active status, scope, and issued time.
538 *[🔗 Endpoint documentation](https://developers.notion.com/reference/introspect-token)*
539 """ # noqa: E501
540 return self.parent.request(
541 path="oauth/introspect",
542 method="POST",
543 body=pick(kwargs, "token"),
544 auth={"client_id": client_id, "client_secret": client_secret},
545 )
547 def revoke(
548 self, client_id: str, client_secret: str, **kwargs: Any
549 ) -> SyncAsync[Any]:
550 """Revoke an access token.
552 *[🔗 Endpoint documentation](https://developers.notion.com/reference/revoke-token)*
553 """ # noqa: E501
554 return self.parent.request(
555 path="oauth/revoke",
556 method="POST",
557 body=pick(kwargs, "token"),
558 auth={"client_id": client_id, "client_secret": client_secret},
559 )