{"id":13594862,"url":"https://github.com/ramnes/notion-sdk-py","last_synced_at":"2025-05-12T13:16:01.662Z","repository":{"id":41273061,"uuid":"367164562","full_name":"ramnes/notion-sdk-py","owner":"ramnes","description":"The official Notion API client library, but rewritten in Python! (sync + async)","archived":false,"fork":false,"pushed_at":"2025-04-17T13:49:38.000Z","size":4088,"stargazers_count":1969,"open_issues_count":10,"forks_count":156,"subscribers_count":23,"default_branch":"main","last_synced_at":"2025-05-07T11:47:34.785Z","etag":null,"topics":["api-client","async","dataclasses","httpx","notion","notion-api","python","python-client"],"latest_commit_sha":null,"homepage":"https://ramnes.github.io/notion-sdk-py","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ramnes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":["https://paypal.me/ramnes"]}},"created_at":"2021-05-13T20:17:52.000Z","updated_at":"2025-05-07T05:00:40.000Z","dependencies_parsed_at":"2023-02-08T18:46:11.427Z","dependency_job_id":"2e23f297-fb87-48f6-bfcd-9c4f4010aa8f","html_url":"https://github.com/ramnes/notion-sdk-py","commit_stats":{"total_commits":205,"total_committers":32,"mean_commits":6.40625,"dds":"0.30243902439024395","last_synced_commit":"9cb98b2e29c1370af865f1c268e3c3d933f61ef9"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramnes%2Fnotion-sdk-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramnes%2Fnotion-sdk-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramnes%2Fnotion-sdk-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramnes%2Fnotion-sdk-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ramnes","download_url":"https://codeload.github.com/ramnes/notion-sdk-py/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253745196,"owners_count":21957319,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","async","dataclasses","httpx","notion","notion-api","python","python-client"],"created_at":"2024-08-01T16:01:40.138Z","updated_at":"2025-05-12T13:16:00.880Z","avatar_url":"https://github.com/ramnes.png","language":"Python","funding_links":["https://paypal.me/ramnes"],"categories":["Python","HarmonyOS","Third-party Web APIs"],"sub_categories":["Windows Manager"],"readme":"\u003c!-- markdownlint-disable --\u003e\n![notion-sdk-py](https://socialify.git.ci/ramnes/notion-sdk-py/image?font=Bitter\u0026language=1\u0026logo=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2F4%2F45%2FNotion_app_logo.png\u0026owner=1\u0026pattern=Circuit%20Board\u0026theme=Light)\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp\u003e\n    \u003ca href=\"https://pypi.org/project/notion-client\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/notion-client.svg\" alt=\"PyPI\"\u003e\u003c/a\u003e\n    \u003ca href=\"tox.ini\"\u003e\u003cimg src=\"https://img.shields.io/pypi/pyversions/notion-client\" alt=\"Supported Python Versions\"\u003e\u003c/a\u003e\n    \u003cbr/\u003e\n    \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/ramnes/notion-sdk-py\" alt=\"License\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ambv/black\"\u003e\u003cimg src=\"https://img.shields.io/badge/code%20style-black-black\" alt=\"Code style\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://codecov.io/github/ramnes/notion-sdk-py\"\u003e\u003cimg src=\"https://codecov.io/gh/ramnes/notion-sdk-py/branch/main/graphs/badge.svg\" alt=\"Coverage\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypistats.org/packages/notion-client\"\u003e\u003cimg src=\"https://img.shields.io/pypi/dm/notion-client\" alt=\"Package downloads\"\u003e\u003c/a\u003e\n    \u003cbr/\u003e\n    \u003ca href=\"https://github.com/ramnes/notion-sdk-py/actions/workflows/quality.yml\"\u003e\u003cimg src=\"https://github.com/ramnes/notion-sdk-py/actions/workflows/quality.yml/badge.svg\" alt=\"Code Quality\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ramnes/notion-sdk-py/actions/workflows/test.yml\"\u003e\u003cimg src=\"https://github.com/ramnes/notion-sdk-py/actions/workflows/test.yml/badge.svg\" alt=\"Tests\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ramnes/notion-sdk-py/actions/workflows/docs.yml\"\u003e\u003cimg src=\"https://github.com/ramnes/notion-sdk-py/actions/workflows/docs.yml/badge.svg\" alt=\"Docs\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-enable --\u003e\n\n**_notion-sdk-py_ is a simple and easy to use client library for the official\n[Notion API](https://developers.notion.com/).**\n\nIt is meant to be a Python version of the reference [JavaScript SDK](https://github.com/makenotion/notion-sdk-js),\nso usage should be very similar between both. 😊 (If not, please open an issue\nor PR!)\n\n\u003e 📢 **Announcement** (18-12-2024) — Release 2.3.0 is out! It adds\n\u003e `in_trash` support for pages, Python 3.13 official support, fixes\n\u003e and security updates.\n\n\u003c!-- markdownlint-disable --\u003e\n## Installation\n\u003c!-- markdownlint-enable --\u003e\n```shell\npip install notion-client\n```\n\n## Usage\n\n\u003e Use Notion's [Getting Started Guide](https://developers.notion.com/docs/getting-started)\n\u003e to get set up to use Notion's API.\n\nImport and initialize a client using an **integration token** or an\nOAuth **access token**.\n\n```python\nimport os\nfrom notion_client import Client\n\nnotion = Client(auth=os.environ[\"NOTION_TOKEN\"])\n```\n\nIn an asyncio environment, use the asynchronous client instead:\n\n```python\nfrom notion_client import AsyncClient\n\nnotion = AsyncClient(auth=os.environ[\"NOTION_TOKEN\"])\n```\n\nMake a request to any Notion API endpoint.\n\n\u003e See the complete list of endpoints in the [API reference](https://developers.notion.com/reference).\n\n```python\nfrom pprint import pprint\n\nlist_users_response = notion.users.list()\npprint(list_users_response)\n```\n\nor with the asynchronous client:\n\n```python\nlist_users_response = await notion.users.list()\npprint(list_users_response)\n```\n\nThis would output something like:\n\n```text\n{'results': [{'avatar_url': 'https://secure.notion-static.com/e6a352a8-8381-44d0-a1dc-9ed80e62b53d.jpg',\n              'id': 'd40e767c-d7af-4b18-a86d-55c61f1e39a4',\n              'name': 'Avocado Lovelace',\n              'object': 'user',\n              'person': {'email': 'avo@example.org'},\n              'type': 'person'},\n             ...]}\n```\n\nAll API endpoints are available in both the synchronous and asynchronous clients.\n\nEndpoint parameters are grouped into a single object. You don't need to remember\nwhich parameters go in the path, query, or body.\n\n```python\nmy_page = notion.databases.query(\n    **{\n        \"database_id\": \"897e5a76-ae52-4b48-9fdf-e71f5945d1af\",\n        \"filter\": {\n            \"property\": \"Landmark\",\n            \"rich_text\": {\n                \"contains\": \"Bridge\",\n            },\n        },\n    }\n)\n```\n\n### Handling errors\n\nIf the API returns an unsuccessful response, an `APIResponseError` will be raised.\n\nThe error contains properties from the response, and the most helpful is `code`.\nYou can compare `code` to the values in the `APIErrorCode` object to avoid\nmisspelling error codes.\n\n```python\nimport logging\nfrom notion_client import APIErrorCode, APIResponseError\n\ntry:\n    my_page = notion.databases.query(\n        **{\n            \"database_id\": \"897e5a76-ae52-4b48-9fdf-e71f5945d1af\",\n            \"filter\": {\n                \"property\": \"Landmark\",\n                \"rich_text\": {\n                    \"contains\": \"Bridge\",\n                },\n            },\n        }\n    )\nexcept APIResponseError as error:\n    if error.code == APIErrorCode.ObjectNotFound:\n        ...  # For example: handle by asking the user to select a different database\n    else:\n        # Other error handling code\n        logging.error(error)\n```\n\n### Logging\n\nThe client emits useful information to a logger. By default, it only emits warnings\nand errors.\n\nIf you're debugging an application, and would like the client to log request \u0026 response\nbodies, set the `log_level` option to `logging.DEBUG`.\n\n```python\nnotion = Client(\n    auth=os.environ[\"NOTION_TOKEN\"],\n    log_level=logging.DEBUG,\n)\n```\n\nYou may also set a custom `logger` to emit logs to a destination other than `stdout`.\nHave a look at [Python's logging cookbook](https://docs.python.org/3/howto/logging-cookbook.html)\nif you want to create your own logger.\n\n### Client options\n\n`Client` and `AsyncClient` both support the following options on initialization.\nThese options are all keys in the single constructor parameter.\n\n\u003c!-- markdownlint-disable --\u003e\n| Option | Default value | Type | Description |\n|--------|---------------|---------|-------------|\n| `auth` | `None` | `string` | Bearer token for authentication. If left undefined, the `auth` parameter should be set on each request. |\n| `log_level` | `logging.WARNING` | `int` | Verbosity of logs the instance will produce. By default, logs are written to `stdout`.\n| `timeout_ms` | `60_000` | `int` | Number of milliseconds to wait before emitting a `RequestTimeoutError` |\n| `base_url` | `\"https://api.notion.com\"` | `string` | The root URL for sending API requests. This can be changed to test with a mock server. |\n| `logger` | Log to console | `logging.Logger` | A custom logger. |\n\n### Full API responses\n\nThe following functions can distinguish between full and partial API responses.\n\n| Function                   | Purpose                                                                                                                                                                  |\n| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `is_full_page`             | Determine whether an object is a full [Page object](https://developers.notion.com/reference/page)                                                                        |\n| `is_full_block`            | Determine whether an object is a full [Block object](https://developers.notion.com/reference/block)                                                                      |\n| `is_full_database`         | Determine whether an object is a full [Database object](https://developers.notion.com/reference/database)                                                                |\n| `is_full_page_or_database` | Determine whether an object is a full [Page object](https://developers.notion.com/reference/page) or [Database object](https://developers.notion.com/reference/database) |\n| `is_full_user`             | Determine whether an object is a full [User object](https://developers.notion.com/reference/user)                                                                        |\n| `is_full_comment`          | Determine whether an object is a full [Comment object](https://developers.notion.com/reference/comment-object)                                                           |\n\u003c!-- markdownlint-enable --\u003e\n\n```python\nfrom notion_client.helpers import is_full_page\n\nfull_or_partial_pages = await notion.databases.query(\n    database_id=\"897e5a76-ae52-4b48-9fdf-e71f5945d1af\"\n)\n\nfor page in full_or_partial_pages[\"results\"]:\n    if not is_full_page_or_database(page):\n        continue\n    print(f\"Created at: {page['created_time']}\")\n```\n\n### Utility functions\n\nThese functions can be helpful for dealing with any of the paginated APIs.\n\n`iterate_paginated_api(function, **kwargs)` and its async version\n`async_iterate_paginated_api(function, **kwargs)` turn any paginated API into a generator.\n\nThe `function` parameter must accept a `start_cursor` argument. Example: `notion.blocks.children.list`.\n\n```python\nfrom notion_client.helpers import iterate_paginated_api\n\nfor block in iterate_paginated_api(\n    notion.databases.query, database_id=\"897e5a76-ae52-4b48-9fdf-e71f5945d1af\"\n):\n    # Do something with block.\n    ...\n```\n\nIf you don't need a generator, `collect_paginated_api(function, **kwargs)` and\nits async version `async_collect_paginated_api(function, **kwargs)` have the\nsame behavior than the previous functions, but return a list of all results\nfrom the paginated API.\n\n```python\nfrom notion_client.helpers import collect_paginated_api\n\nall_results = collect_paginated_api(\n    notion.databases.query, database_id=\"897e5a76-ae52-4b48-9fdf-e71f5945d1af\"\n)\n```\n\n## Testing\n\nRun the tests with the `pytest` command. If you want to test against all Python\nversions, you can run `tox` instead.\n\nThe tests are using `pytest-vcr`'s cassettes for simulating requests to the\nNotion API. To create new tests or run them without cassettes, you need to set\nup the environment variables `NOTION_TOKEN` and `NOTION_TEST_PAGE_ID` (a page\nwhere your integration has all the capabilities enabled).\n\nThe code will use the page at `NOTION_TEST_PAGE_ID` to generate a temporary\nenvironment with the Notion objects to be tested, which will be deleted\nat the end of the session.\n\n## Requirements\n\nThis package supports the following minimum versions:\n\n* Python \u003e= 3.7\n* httpx \u003e= 0.23.0\n\nEarlier versions may still work, but we encourage people building new applications\nto upgrade to the current stable.\n\n## Getting help\n\nIf you want to submit a feature request for Notion's API, or are experiencing\nany issues with the API platform, please email `developers@makenotion.com`.\n\nIf you found a bug with the library, please [submit an issue](https://github.com/ramnes/notion-sdk-py/issues).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Framnes%2Fnotion-sdk-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Framnes%2Fnotion-sdk-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Framnes%2Fnotion-sdk-py/lists"}