Skip to main content

A high-level Python SDK for the Notion API with developer experience in mind.

Project description

Better Notion

A pythonic, object-oriented SDK for the Notion API.

PyPI Python Tests Coverage


🚀 Quick Start

pip install better-notion
import asyncio
from better_notion import NotionAPI

async def main():
    async with NotionAPI(auth="secret_...") as api:
        # Get a page
        page = await api.pages.get("page_id")
        print(page.properties)

        # List pages in a database
        async for page in api.pages.iterate("database_id"):
            print(page.title)

asyncio.run(main())

✨ Why Better Notion?

  • 🎯 Object-Oriented: Work with entities, not JSON dicts
  • 🔋 Type-Safe: Property builders for compile-time safety
  • 📄 Paginated: Automatic cursor-based pagination
  • 🔍 Powerful Search: Search across your entire workspace
  • ⚡ Async-First: Built with asyncio and httpx for performance

📦 Installation

# With pip
pip install better-notion

# With uv
uv pip install better-notion

🔑 Authentication

Create an integration at notion.so/my-integrations to get your API token.

from better_notion import NotionAPI

api = NotionAPI(auth="secret_...")

📚 Features

Entities

All Notion objects are represented as Python entities:

  • Pages - Create, read, update, delete, archive
  • Blocks - Manipulate content blocks
  • Databases - Query and manage databases
  • Users - Retrieve user information

Property Builders

Type-safe builders for all Notion property types:

from better_notion.properties import Title, Select, Date, Checkbox

properties = {
    **Title("My Page").build(),
    **Select("Status", "In Progress").build(),
    **Date("Due Date", "2025-01-15").build(),
    **Checkbox("Done", False).build(),
}

Automatic Pagination

Memory-efficient iteration over large datasets:

async for page in api.pages.iterate("database_id"):
    # Processes pages lazily, not all at once
    process(page)

💡 Usage Examples

Creating a Page

from better_notion import NotionAPI
from better_notion.properties import Title, Text

async def create_page():
    async with NotionAPI(auth="secret_...") as api:
        page = await api.pages.create(
            parent={"database_id": "database_id"},
            properties={
                **Title("My New Page").build(),
                **Text("Notes", "Some notes").build(),
            }
        )
        print(f"Created page: {page.id}")

Updating a Page

from better_notion.properties import Select

async def update_page():
    async with NotionAPI(auth="secret_...") as api:
        page = await api.pages.get("page_id")

        # Update properties locally
        await page.update(
            **Select("Status", "Done").build()
        )

        # Save changes to Notion
        await page.save()

Working with Blocks

async def manipulate_blocks():
    async with NotionAPI(auth="secret_...") as api:
        page = await api.pages.get("page_id")

        # Get children blocks
        children = await page.blocks.children()

        # Append a new block
        await page.blocks.append(children=[
            {
                "object": "block",
                "type": "paragraph",
                "paragraph": {
                    "text": [{"text": {"content": "New paragraph"}}]
                }
            }
        ])

Searching

async def search_pages():
    async with NotionAPI(auth="secret_...") as api:
        # Search for pages matching query
        async for result in api.search_iterate("my query"):
            if result["object"] == "page":
                print(result["properties"]["title"])

📖 API Reference

NotionAPI

The main client for interacting with Notion.

Methods:

  • search(query, *, filter, sort) - Search pages and blocks
  • search_iterate(query, *, filter, sort) - Iterate over search results

Collections:

  • api.pages - PageCollection
  • api.blocks - BlockCollection
  • api.databases - DatabaseCollection
  • api.users - UserCollection

Page

Properties:

  • id - Page ID
  • created_time - Creation datetime
  • last_edited_time - Last edited datetime
  • archived - Whether page is archived
  • properties - Page properties dict
  • blocks - BlockCollection for children

Methods:

  • await save() - Save changes to Notion
  • await delete() - Archive page
  • await reload() - Reload from Notion
  • await update(**kwargs) - Update properties locally

Block

Properties:

  • id - Block ID
  • type - Block type (paragraph, heading, etc.)
  • content - Block content

Methods:

  • await save() - Save changes to Notion
  • await delete() - Delete block
  • await reload() - Reload from Notion

Collections

PageCollection

  • await get(page_id) - Retrieve a page
  • await create(**kwargs) - Create a new page
  • await list(database_id, **kwargs) - List pages (first page)
  • iterate(database_id, **kwargs) - Iterate over all pages

BlockCollection

  • await get(block_id) - Retrieve a block
  • await children() - Get children blocks
  • await append(**kwargs) - Append new blocks

DatabaseCollection

  • await get(database_id) - Retrieve a database
  • await query(database_id, **kwargs) - Query a database
  • await create_page(database_id, **kwargs) - Create a page in database

UserCollection

  • await get(user_id) - Retrieve a user
  • await list() - List all users
  • await me() - Get current bot user

🤝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

Development

# Clone the repository
git clone https://github.com/nesalia-inc/better-notion.git

# Install with dev dependencies
uv sync

# Run tests
uv run pytest

# Run with coverage
uv run pytest --cov=better_notion

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.


🔗 Links


🙏 Acknowledgments

Built with ❤️ using:

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

better_notion-0.1.0.tar.gz (23.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

better_notion-0.1.0-py3-none-any.whl (27.9 kB view details)

Uploaded Python 3

File details

Details for the file better_notion-0.1.0.tar.gz.

File metadata

  • Download URL: better_notion-0.1.0.tar.gz
  • Upload date:
  • Size: 23.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for better_notion-0.1.0.tar.gz
Algorithm Hash digest
SHA256 147d23ae93785507b13a8125c5692c2d8de11a7fe227d543155587ae7b701bba
MD5 0f69c217da67c358505f3ba571a10260
BLAKE2b-256 d30aae7da1c63ed34c6a93a36282faa8f3ba991202f122da2b085935c5807df1

See more details on using hashes here.

File details

Details for the file better_notion-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: better_notion-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 27.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for better_notion-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5cef95fa99474a7f24f42fac4befd6e1763fa39091d2e48c5f1ae9dde3216db7
MD5 903059b6b0a660cea59903df860eda0f
BLAKE2b-256 d08460fdd880583b3d99552a4528c99764881d6ae98ff7faf15b2dbdd746ffca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page