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

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 "template", 

277 "position", 

278 ), 

279 auth=kwargs.get("auth"), 

280 ) 

281 

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. 

284 

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 ) 

293 

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. 

296 

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 ) 

315 

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. 

318 

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 ) 

327 

328 

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. 

332 

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 ) 

341 

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. 

344 

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 ) 

350 

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

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

353 

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 ) 

359 

360 

361class SearchEndpoint(Endpoint): 

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

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

364 

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 ) 

373 

374 

375class CommentsEndpoint(Endpoint): 

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

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

378 

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 ) 

394 

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. 

397 

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 ) 

406 

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

409 

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 ) 

417 

418 

419class FileUploadsEndpoint(Endpoint): 

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

421 """Create a file upload. 

422 

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 ) 

438 

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

440 """Complete the file upload process. 

441 

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 ) 

449 

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

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

452 

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 ) 

460 

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

462 """List all file uploads. 

463 

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 ) 

472 

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

474 """Send a file upload 

475 

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 ) 

484 

485 

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. 

491 

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 ) 

507 

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. 

512 

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 ) 

521 

522 def revoke( 

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

524 ) -> SyncAsync[Any]: 

525 """Revoke an access token. 

526 

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 )