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

1"""Notion API endpoints.""" # noqa: E501 

2 

3from typing import TYPE_CHECKING, Any 

4 

5from notion_client.helpers import pick 

6from notion_client.typing import SyncAsync 

7 

8if TYPE_CHECKING: # pragma: no cover 

9 from notion_client.client import BaseClient 

10 

11 

12class Endpoint: 

13 def __init__(self, parent: "BaseClient") -> None: 

14 self.parent = parent 

15 

16 

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. 

20 

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 ) 

29 

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. 

32 

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 ) 

41 

42 

43class BlocksEndpoint(Endpoint): 

44 def __init__(self, *args: Any, **kwargs: Any) -> None: 

45 super().__init__(*args, **kwargs) 

46 self.children = BlocksChildrenEndpoint(*args, **kwargs) 

47 

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. 

50 

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 ) 

56 

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. 

59 

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 ) 

101 

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`. 

104 

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 ) 

112 

113 

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. 

117 

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 ) 

125 

126 def update(self, database_id: str, **kwargs: Any) -> SyncAsync[Any]: 

127 """Update the title or properties of an existing database. 

128 

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 ) 

147 

148 def create(self, **kwargs: Any) -> SyncAsync[Any]: 

149 """Create a new database. 

150 

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 ) 

168 

169 

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. 

173 

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 ) 

179 

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. 

182 

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 ) 

201 

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). 

204 

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 ) 

213 

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. 

216 

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 ) 

227 

228 def list_templates(self, data_source_id: str, **kwargs: Any) -> SyncAsync[Any]: 

229 """List page templates that are available for a data source. 

230 

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 ) 

239 

240 

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`. 

244 

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 ) 

253 

254 

255class PagesEndpoint(Endpoint): 

256 def __init__(self, *args: Any, **kwargs: Any) -> None: 

257 super().__init__(*args, **kwargs) 

258 self.properties = PagesPropertiesEndpoint(*args, **kwargs) 

259 

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. 

262 

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 ) 

282 

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. 

285 

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 ) 

294 

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. 

297 

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 ) 

316 

317 def retrieve_markdown(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]: 

318 """Retrieve a page as markdown. 

319 

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 ) 

328 

329 def update_markdown(self, page_id: str, **kwargs: Any) -> SyncAsync[Any]: 

330 """Update a page's content as markdown. 

331 

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 ) 

340 

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. 

343 

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 ) 

352 

353 

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. 

357 

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 ) 

366 

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. 

369 

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 ) 

375 

376 def me(self, **kwargs: Any) -> SyncAsync[Any]: 

377 """Retrieve the bot [User](https://developers.notion.com/reference/user) associated with the API token. 

378 

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 ) 

384 

385 

386class SearchEndpoint(Endpoint): 

387 def __call__(self, **kwargs: Any) -> SyncAsync[Any]: 

388 """Search all pages and child pages that are shared with the integration. 

389 

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 ) 

398 

399 

400class CommentsEndpoint(Endpoint): 

401 def create(self, **kwargs: Any) -> SyncAsync[Any]: 

402 """Create a new comment in the specified page or existing discussion thread. 

403 

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 ) 

419 

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. 

422 

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 ) 

431 

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`. 

434 

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 ) 

442 

443 

444class FileUploadsEndpoint(Endpoint): 

445 def create(self, **kwargs: Any) -> SyncAsync[Any]: 

446 """Create a file upload. 

447 

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 ) 

463 

464 def complete(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]: 

465 """Complete the file upload process. 

466 

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 ) 

474 

475 def retrieve(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]: 

476 """Retrieve a file upload object using the ID specified. 

477 

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 ) 

485 

486 def list(self, **kwargs: Any) -> SyncAsync[Any]: 

487 """List all file uploads. 

488 

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 ) 

497 

498 def send(self, file_upload_id: str, **kwargs: Any) -> SyncAsync[Any]: 

499 """Send a file upload 

500 

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 ) 

509 

510 

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. 

516 

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 ) 

532 

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. 

537 

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 ) 

546 

547 def revoke( 

548 self, client_id: str, client_secret: str, **kwargs: Any 

549 ) -> SyncAsync[Any]: 

550 """Revoke an access token. 

551 

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 )