Package: notion-client
notion-sdk-pyis a simple and easy to use client library for the officialNotion API.It is meant to be a Python version of the referenceJavaScript SDK,
so usage should be very similar between both. 😊 (If not, please open an issue
or PR!)📢Announcement(28-12-2023) — Release 2.2.1 is out and fixes iteration helpers.What's new in 2.2.0 (26-12-2023):Icons and covers can now be removed from pages.filter_propertieshas been added tonotion.pages.retrieve.You can now pass your ownstart_cursorin the iteration helpers.Installationpipinstallnotion-clientUsageUse Notion'sGetting Started Guideto get set up to use Notion's API.Import and initialize a client using anintegration tokenor an
OAuthaccess token.importosfromnotion_clientimportClientnotion=Client(auth=os.environ["NOTION_TOKEN"])In an asyncio environment, use the asynchronous client instead:fromnotion_clientimportAsyncClientnotion=AsyncClient(auth=os.environ["NOTION_TOKEN"])Make a request to any Notion API endpoint.See the complete list of endpoints in theAPI reference.frompprintimportpprintlist_users_response=notion.users.list()pprint(list_users_response)or with the asynchronous client:list_users_response=awaitnotion.users.list()pprint(list_users_response)This would output something like:{'results': [{'avatar_url': 'https://secure.notion-static.com/e6a352a8-8381-44d0-a1dc-9ed80e62b53d.jpg',
              'id': 'd40e767c-d7af-4b18-a86d-55c61f1e39a4',
              'name': 'Avocado Lovelace',
              'object': 'user',
              'person': {'email': 'avo@example.org'},
              'type': 'person'},
             ...]}All API endpoints are available in both the synchronous and asynchronous clients.Endpoint parameters are grouped into a single object. You don't need to remember
which parameters go in the path, query, or body.my_page=notion.databases.query(**{"database_id":"897e5a76-ae52-4b48-9fdf-e71f5945d1af","filter":{"property":"Landmark","rich_text":{"contains":"Bridge",},},})Handling errorsIf the API returns an unsuccessful response, anAPIResponseErrorwill be raised.The error contains properties from the response, and the most helpful iscode.
You can comparecodeto the values in theAPIErrorCodeobject to avoid
misspelling error codes.importloggingfromnotion_clientimportAPIErrorCode,APIResponseErrortry:my_page=notion.databases.query(**{"database_id":"897e5a76-ae52-4b48-9fdf-e71f5945d1af","filter":{"property":"Landmark","rich_text":{"contains":"Bridge",},},})exceptAPIResponseErroraserror:iferror.code==APIErrorCode.ObjectNotFound:...# For example: handle by asking the user to select a different databaseelse:# Other error handling codelogging.error(error)LoggingThe client emits useful information to a logger. By default, it only emits warnings
and errors.If you're debugging an application, and would like the client to log request & response
bodies, set thelog_leveloption tologging.DEBUG.notion=Client(auth=os.environ["NOTION_TOKEN"],log_level=logging.DEBUG,)You may also set a customloggerto emit logs to a destination other thanstdout.
Have a look atPython's logging cookbookif you want to create your own logger.Client optionsClientandAsyncClientboth support the following options on initialization.
These options are all keys in the single constructor parameter.OptionDefault valueTypeDescriptionauthNonestringBearer token for authentication. If left undefined, theauthparameter should be set on each request.log_levellogging.WARNINGintVerbosity of logs the instance will produce. By default, logs are written tostdout.timeout_ms60_000intNumber of milliseconds to wait before emitting aRequestTimeoutErrorbase_url"https://api.notion.com"stringThe root URL for sending API requests. This can be changed to test with a mock server.loggerLog to consolelogging.LoggerA custom logger.Full API responsesThe following functions can distinguish between full and partial API responses.FunctionPurposeis_full_pageDetermine whether an object is a fullPage objectis_full_blockDetermine whether an object is a fullBlock objectis_full_databaseDetermine whether an object is a fullDatabase objectis_full_page_or_databaseDetermine whether an object is a fullPage objectorDatabase objectis_full_userDetermine whether an object is a fullUser objectis_full_commentDetermine whether an object is a fullComment objectfromnotion_client.helpersimportis_full_pagefull_or_partial_pages=awaitnotion.databases.query(database_id="897e5a76-ae52-4b48-9fdf-e71f5945d1af")forpageinfull_or_partial_pages["results"]:ifnotis_full_page_or_database(page):continueprint(f"Created at:{page['created_time']}")Utility functionsThese functions can be helpful for dealing with any of the paginated APIs.iterate_paginated_api(function, **kwargs)and its async versionasync_iterate_paginated_api(function, **kwargs)turn any paginated API into a generator.Thefunctionparameter must accept astart_cursorargument. Example:notion.blocks.children.list.fromnotion_client.helpersimportiterate_paginated_apiforblockiniterate_paginated_api(notion.databases.query,database_id="897e5a76-ae52-4b48-9fdf-e71f5945d1af"):# Do something with block....If you don't need a generator,collect_paginated_api(function, **kwargs)and
its async versionasync_collect_paginated_api(function, **kwargs)have the
same behavior than the previous functions, but return a list of all results
from the paginated API.fromnotion_client.helpersimportcollect_paginated_apiall_results=collect_paginated_api(notion.databases.query,database_id="897e5a76-ae52-4b48-9fdf-e71f5945d1af")TestingRun the tests with thepytestcommand. If you want to test against all Python
versions, you can runtoxinstead.The tests are usingpytest-vcr's cassettes for simulating requests to the
Notion API. To create new tests or run them without cassettes, you need to set
up the environment variablesNOTION_TOKENandNOTION_TEST_PAGE_ID(a page
where your integration has all the capabilities enabled).The code will use the page atNOTION_TEST_PAGE_IDto generate a temporary
environment with the Notion objects to be tested, which will be deleted
at the end of the session.RequirementsThis package supports the following minimum versions:Python >= 3.7httpx >= 0.15.0Earlier versions may still work, but we encourage people building new applications
to upgrade to the current stable.Getting helpIf you want to submit a feature request for Notion's API, or are experiencing
any issues with the API platform, please emaildevelopers@makenotion.com.If you found a bug with the library, pleasesubmit an issue.